rlottie: Supports the Transform Position property.
authorJunsuChoi <jsuya.choi@samsung.com>
Tue, 31 Dec 2019 07:37:31 +0000 (16:37 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Tue, 7 Jan 2020 21:36:59 +0000 (06:36 +0900)
Use setValue<rlottie::Property::TrPosition> and return rlottie::Point type.
Example) example/demo

example/demo.cpp
src/binding/c/lottieanimation_capi.cpp
src/lottie/lottieitem.cpp
src/lottie/lottieitem.h
src/lottie/lottieproxymodel.h

index c38da60..23d5c76 100644 (file)
@@ -31,14 +31,15 @@ public:
         Demo1(app, filePath);
         Demo2(app, filePath);
         Demo3(app, filePath);
-
+        Demo4(app, filePath);
+        Demo5(app, filePath);
     }
     void Demo1(EvasApp *app, std::string &filePath) {
         /* Fill Color */
-        view.reset(new LottieView(app->evas()));
-        view->setFilePath(filePath.c_str());
-        if (view->player()) {
-            view->player()->setValue<rlottie::Property::FillColor>("Shape Layer 1.Ellipse 1.Fill 1",
+        view1.reset(new LottieView(app->evas()));
+        view1->setFilePath(filePath.c_str());
+        if (view1->player()) {
+            view1->player()->setValue<rlottie::Property::FillColor>("Shape Layer 1.Ellipse 1.Fill 1",
                 [](const rlottie::FrameInfo& info) {
                      if (info.curFrame() < 60 )
                          return rlottie::Color(0, 0, 1);
@@ -47,20 +48,20 @@ public:
                      }
                  });
         }
-        view->setPos(0, 0);
-        view->setSize(300, 300);
-        view->show();
-        view->play();
-        view->loop(true);
-        view->setRepeatMode(LottieView::RepeatMode::Reverse);
+        view1->setPos(0, 0);
+        view1->setSize(300, 300);
+        view1->show();
+        view1->play();
+        view1->loop(true);
+        view1->setRepeatMode(LottieView::RepeatMode::Reverse);
     }
 
     void Demo2(EvasApp *app, std::string &filePath) {
         /* Stroke Opacity */
-        view1.reset(new LottieView(app->evas()));
-        view1->setFilePath(filePath.c_str());
-        if (view1->player()) {
-            view1->player()->setValue<rlottie::Property::StrokeOpacity>("Shape Layer 2.Shape 1.Stroke 1",
+        view2.reset(new LottieView(app->evas()));
+        view2->setFilePath(filePath.c_str());
+        if (view2->player()) {
+            view2->player()->setValue<rlottie::Property::StrokeOpacity>("Shape Layer 2.Shape 1.Stroke 1",
                 [](const rlottie::FrameInfo& info) {
                      if (info.curFrame() < 60 )
                          return 20;
@@ -69,20 +70,20 @@ public:
                      }
                  });
         }
-        view1->setPos(300, 0);
-        view1->setSize(300, 300);
-        view1->show();
-        view1->play();
-        view1->loop(true);
-        view1->setRepeatMode(LottieView::RepeatMode::Reverse);
+        view2->setPos(300, 0);
+        view2->setSize(300, 300);
+        view2->show();
+        view2->play();
+        view2->loop(true);
+        view2->setRepeatMode(LottieView::RepeatMode::Reverse);
     }
 
     void Demo3(EvasApp *app, std::string &filePath) {
         /* Stroke Opacity */
-        view2.reset(new LottieView(app->evas()));
-        view2->setFilePath(filePath.c_str());
-        if (view2->player()) {
-            view2->player()->setValue<rlottie::Property::StrokeWidth>("**",
+        view3.reset(new LottieView(app->evas()));
+        view3->setFilePath(filePath.c_str());
+        if (view3->player()) {
+            view3->player()->setValue<rlottie::Property::StrokeWidth>("**",
                     [](const rlottie::FrameInfo& info) {
                           if (info.curFrame() < 60 )
                               return 1.0;
@@ -91,18 +92,57 @@ public:
                            }
                     });
         }
-        view2->setPos(600, 0);
-        view2->setSize(300, 300);
-        view2->show();
-        view2->play();
-        view2->loop(true);
-        view2->setRepeatMode(LottieView::RepeatMode::Reverse);
+        view3->setPos(600, 0);
+        view3->setSize(300, 300);
+        view3->show();
+        view3->play();
+        view3->loop(true);
+        view3->setRepeatMode(LottieView::RepeatMode::Reverse);
+    }
+
+    void Demo4(EvasApp *app, std::string &filePath) {
+        /* Transform position */
+        view4.reset(new LottieView(app->evas()));
+        view4->setFilePath(filePath.c_str());
+        if (view4->player()) {
+            view4->player()->setValue<rlottie::Property::TrPosition>("Shape Layer 1.Ellipse 1",
+                [](const rlottie::FrameInfo& info) {
+                          return rlottie::Point(-20 + (double)info.curFrame()/2.0,
+                                                -20 + (double)info.curFrame()/2.0);
+                 });
+        }
+        view4->setPos(900, 0);
+        view4->setSize(300, 300);
+        view4->show();
+        view4->play();
+        view4->loop(true);
+        view4->setRepeatMode(LottieView::RepeatMode::Reverse);
     }
 
+    void Demo5(EvasApp *app, std::string &filePath) {
+        /* Transform position */
+        view5.reset(new LottieView(app->evas()));
+        view5->setFilePath(filePath.c_str());
+        if (view5->player()) {
+            view5->player()->setValue<rlottie::Property::TrPosition>("Shape Layer 2.Shape 1",
+                [](const rlottie::FrameInfo& info) {
+                          return rlottie::Point(-20 + (double)info.curFrame()/2.0,
+                                                -20 + (double)info.curFrame()/2.0);
+                 });
+        }
+        view5->setPos(1200, 0);
+        view5->setSize(300, 300);
+        view5->show();
+        view5->play();
+        view5->loop(true);
+        view5->setRepeatMode(LottieView::RepeatMode::Reverse);
+    }
 private:
-    std::unique_ptr<LottieView>  view;
     std::unique_ptr<LottieView>  view1;
     std::unique_ptr<LottieView>  view2;
+    std::unique_ptr<LottieView>  view3;
+    std::unique_ptr<LottieView>  view4;
+    std::unique_ptr<LottieView>  view5;
 };
 
 static void
@@ -115,7 +155,7 @@ onExitCb(void *data, void */*extra*/)
 int
 main(void)
 {
-   EvasApp *app = new EvasApp(900, 300);
+   EvasApp *app = new EvasApp(1500, 300);
    app->setup();
 
    std::string filePath = DEMO_DIR;
index 991ae9f..96473ad 100644 (file)
@@ -204,8 +204,13 @@ lottie_animation_property_override(Lottie_Animation_S *animation,
         animation->mAnimation->setValue<rlottie::Property::StrokeWidth>(keypath, (float)width);
         break;
     }
+    case LOTTIE_ANIMATION_PROPERTY_TR_POSITION: {
+        double x = va_arg(prop, double);
+        double y = va_arg(prop, double);
+        animation->mAnimation->setValue<rlottie::Property::TrPosition>(keypath, rlottie::Point((float)x, (float)y));
+        break;
+    }
     case LOTTIE_ANIMATION_PROPERTY_TR_ANCHOR:
-    case LOTTIE_ANIMATION_PROPERTY_TR_POSITION:
     case LOTTIE_ANIMATION_PROPERTY_TR_SCALE:
     case LOTTIE_ANIMATION_PROPERTY_TR_ROTATION:
     case LOTTIE_ANIMATION_PROPERTY_TR_OPACITY:
index ee0743e..2af7405 100644 (file)
@@ -830,16 +830,18 @@ DrawableList LOTShapeLayerItem::renderList()
 bool LOTContentGroupItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
                                          LOTVariant &value)
 {
-    if (!keyPath.matches(name(), depth)) {
-        return false;
-    }
+   if (!keyPath.skip(name())) {
+        if (!keyPath.matches(mModel.name(), depth)) {
+             return false;
+        }
 
-    if (!keyPath.skip(name())) {
-        if (keyPath.fullyResolvesTo(name(), depth) &&
-            transformProp(value.property())) {
-            //@TODO handle property update
+        if (!keyPath.skip(mModel.name())) {
+             if (keyPath.fullyResolvesTo(mModel.name(), depth) &&
+                 transformProp(value.property())) {
+                  mModel.filter().addValue(value);
+             }
         }
-    }
+   }
 
     if (keyPath.propagate(name(), depth)) {
         uint newDepth = keyPath.nextDepth(name(), depth);
@@ -881,7 +883,7 @@ bool LOTStrokeItem::resolveKeyPath(LOTKeyPath &keyPath, uint depth,
 }
 
 LOTContentGroupItem::LOTContentGroupItem(LOTGroupData *data, VArenaAlloc* allocator)
-    : mData(data)
+    : mData(data), mModel(data)
 {
     addChildren(mData, allocator);
 }
@@ -913,6 +915,11 @@ void LOTContentGroupItem::update(int frameNo, const VMatrix &parentMatrix,
         VMatrix m = mData->mTransform->matrix(frameNo);
         m *= parentMatrix;
 
+        if (mModel.filter().hasFilter(rlottie::Property::TrPosition)){
+             auto ps = mModel.position(frameNo);
+             m.translate(ps.x(), ps.y());
+        }
+
         if (!(flag & DirtyFlagBit::Matrix) && !mData->mTransform->isStatic() &&
             (m != mMatrix)) {
             newFlag |= DirtyFlagBit::Matrix;
index b0b420d..6335785 100644 (file)
@@ -348,6 +348,8 @@ protected:
    LOTGroupData                                  *mData{nullptr};
    std::vector<LOTContentItem*>   mContents;
    VMatrix                                        mMatrix;
+private:
+   LOTProxyModel<LOTGroupData> mModel;
 };
 
 class LOTPathDataItem : public LOTContentItem
index ec4e5fd..72fd22a 100644 (file)
@@ -243,6 +243,12 @@ public:
         rlottie::Color col = data(prop).color()(info);
         return LottieColor(col.r(), col.g(), col.b());
     }
+    VPointF point(rlottie::Property prop, int frame) const
+    {
+        rlottie::FrameInfo info(frame);
+        rlottie::Point pt = data(prop).point()(info);
+        return VPointF(pt.x(), pt.y());
+    }
     float opacity(rlottie::Property prop, int frame) const
     {
         rlottie::FrameInfo info(frame);
@@ -334,4 +340,22 @@ private:
     LOTFilter                  mFilter;
 };
 
+template <>
+class LOTProxyModel<LOTGroupData>
+{
+public:
+    LOTProxyModel(LOTGroupData *model = nullptr): _modelData(model) {}
+    LOTFilter& filter() {return mFilter;}
+    const char* name() const {return _modelData->name();}
+    VPointF position(int frame) const
+    {
+        if (mFilter.hasFilter(rlottie::Property::TrPosition)) {
+            return mFilter.point(rlottie::Property::TrPosition, frame);
+        }
+        return VPointF(_modelData->mTransform->matrix(frame).m_tx(), _modelData->mTransform->matrix(frame).m_ty());
+    }
+private:
+    LOTGroupData               *_modelData;
+    LOTFilter                  mFilter;
+};
 #endif // LOTTIEITEM_H