diff --git a/src/loaders/lottie/tvgLottieModel.cpp b/src/loaders/lottie/tvgLottieModel.cpp index 22c1b269..08b202c7 100644 --- a/src/loaders/lottie/tvgLottieModel.cpp +++ b/src/loaders/lottie/tvgLottieModel.cpp @@ -61,8 +61,26 @@ void LottieSlot::assign(LottieObject* target, bool byDefault) for (auto pair = pairs.begin(); pair < pairs.end(); ++pair) { //backup the original properties before overwriting switch (type) { + case LottieProperty::Type::Position: { + if (copy) pair->prop = new LottiePosition(static_cast(pair->obj)->position); + pair->obj->override(&static_cast(target)->position, shallow, byDefault); + break; + } + case LottieProperty::Type::Point: { + if (copy) pair->prop = new LottiePoint(static_cast(pair->obj)->scale); + pair->obj->override(&static_cast(target)->scale, shallow, byDefault); + break; + } + case LottieProperty::Type::Float: { + if (copy) pair->prop = new LottieFloat(static_cast(pair->obj)->rotation); + pair->obj->override(&static_cast(target)->rotation, shallow, byDefault); + break; + } case LottieProperty::Type::Opacity: { - if (copy) pair->prop = new LottieOpacity(static_cast(pair->obj)->opacity); + if (copy) { + if (pair->obj->type == LottieObject::Type::Transform) pair->prop = new LottieOpacity(static_cast(pair->obj)->opacity); + else pair->prop = new LottieOpacity(static_cast(pair->obj)->opacity); + } pair->obj->override(&static_cast(target)->opacity, shallow, byDefault); break; } diff --git a/src/loaders/lottie/tvgLottieModel.h b/src/loaders/lottie/tvgLottieModel.h index b4ebc60e..15708124 100644 --- a/src/loaders/lottie/tvgLottieModel.h +++ b/src/loaders/lottie/tvgLottieModel.h @@ -550,6 +550,33 @@ struct LottieTransform : LottieObject return nullptr; } + void override(LottieProperty* prop, bool shallow, bool byDefault) override + { + switch (prop->type) { + case LottieProperty::Type::Position: { + if (byDefault) position.release(); + position.copy(*static_cast(prop), shallow); + break; + } + case LottieProperty::Type::Float: { + if (byDefault) rotation.release(); + rotation.copy(*static_cast(prop), shallow); + break; + } + case LottieProperty::Type::Point: { + if (byDefault) scale.release(); + scale.copy(*static_cast(prop), shallow); + break; + } + case LottieProperty::Type::Opacity: { + if (byDefault) opacity.release(); + opacity.copy(*static_cast(prop), shallow); + break; + } + default: break; + } + } + LottiePosition position = Point{0.0f, 0.0f}; LottieFloat rotation = 0.0f; //z rotation LottiePoint scale = Point{100.0f, 100.0f}; diff --git a/src/loaders/lottie/tvgLottieParser.cpp b/src/loaders/lottie/tvgLottieParser.cpp index b0fbf41e..a13fd835 100644 --- a/src/loaders/lottie/tvgLottieParser.cpp +++ b/src/loaders/lottie/tvgLottieParser.cpp @@ -608,14 +608,15 @@ LottieTransform* LottieParser::parseTransform(bool ddd) else if (transform->coords && KEY_AS("x")) parseProperty(transform->coords->x); else if (transform->coords && KEY_AS("y")) parseProperty(transform->coords->y); else if (KEY_AS("x")) transform->position.exp = _expression(getStringCopy(), comp, context.layer, context.parent, &transform->position); + else if (KEY_AS("sid")) registerSlot(transform, getString()); else skip(key); } transform->position.type = LottieProperty::Type::Position; } else if (KEY_AS("a")) parseProperty(transform->anchor); - else if (KEY_AS("s")) parseProperty(transform->scale); - else if (KEY_AS("r")) parseProperty(transform->rotation); - else if (KEY_AS("o")) parseProperty(transform->opacity); + else if (KEY_AS("s")) parseProperty(transform->scale, transform); + else if (KEY_AS("r")) parseProperty(transform->rotation, transform); + else if (KEY_AS("o")) parseProperty(transform->opacity, transform); else if (transform->rotationEx && KEY_AS("rx")) parseProperty(transform->rotationEx->x); else if (transform->rotationEx && KEY_AS("ry")) parseProperty(transform->rotationEx->y); else if (transform->rotationEx && KEY_AS("rz")) parseProperty(transform->rotation); @@ -1582,6 +1583,24 @@ bool LottieParser::apply(LottieSlot* slot, bool byDefault) LottieObject* obj = nullptr; //slot object switch (slot->type) { + case LottieProperty::Type::Position: { + obj = new LottieTransform; + context.parent = obj; + parseSlotProperty(static_cast(obj)->position); + break; + } + case LottieProperty::Type::Point: { + obj = new LottieTransform; + context.parent = obj; + parseSlotProperty(static_cast(obj)->scale); + break; + } + case LottieProperty::Type::Float: { + obj = new LottieTransform; + context.parent = obj; + parseSlotProperty(static_cast(obj)->rotation); + break; + } case LottieProperty::Type::Opacity: { obj = new LottieSolid; context.parent = obj; diff --git a/src/loaders/lottie/tvgLottieProperty.h b/src/loaders/lottie/tvgLottieProperty.h index ed27f183..b3eb5ae6 100644 --- a/src/loaders/lottie/tvgLottieProperty.h +++ b/src/loaders/lottie/tvgLottieProperty.h @@ -741,6 +741,19 @@ struct LottiePosition : LottieProperty return frame->angle(frame + 1, frameNo); } + void copy(const LottiePosition& rhs, bool shallow = true) + { + if (rhs.frames) { + if (shallow) { + frames = rhs.frames; + const_cast(rhs).frames = nullptr; + } else { + frames = new Array>; + *frames = *rhs.frames; + } + } else value = rhs.value; + } + void prepare() { if (!frames || frames->count < 2) return;