submodule: add rive-cpp to rive-tizen as submodule
[platform/core/uifw/rive-tizen.git] / submodule / src / animation / linear_animation_instance.cpp
1 #include "animation/linear_animation_instance.hpp"
2 #include "animation/loop.hpp"
3 #include <cmath>
4
5 using namespace rive;
6
7 LinearAnimationInstance::LinearAnimationInstance(LinearAnimation* animation) :
8     m_Animation(animation),
9     m_Time(animation->enableWorkArea() ? (float) animation->workStart() / animation->fps() : 0),
10     m_Direction(1)
11 {
12 }
13
14 bool LinearAnimationInstance::advance(float elapsedSeconds)
15 {
16         LinearAnimation& animation = *m_Animation;
17         m_Time += elapsedSeconds * animation.speed() * m_Direction;
18
19         int fps = animation.fps();
20
21         float frames = m_Time * fps;
22
23         int start = animation.enableWorkArea() ? animation.workStart() : 0;
24         int end =
25             animation.enableWorkArea() ? animation.workEnd() : animation.duration();
26         int range = end - start;
27
28         bool keepGoing = true;
29         bool didLoop = false;
30
31         switch (animation.loop())
32         {
33                 case Loop::oneShot:
34                         if (frames > end)
35                         {
36                                 keepGoing = false;
37                                 frames = end;
38                                 m_Time = frames / fps;
39                                 didLoop = true;
40                         }
41                         break;
42                 case Loop::loop:
43                         if (frames >= end)
44                         {
45                                 frames = m_Time * fps;
46                                 frames = start + std::fmod(frames - start, range);
47                                 m_Time = frames / fps;
48                                 didLoop = true;
49                         }
50                         break;
51                 case Loop::pingPong:
52                         while (true)
53                         {
54                                 if (m_Direction == 1 && frames >= end)
55                                 {
56                                         m_Direction = -1;
57                                         frames = end + (end - frames);
58                                         m_Time = frames / fps;
59                                         didLoop = true;
60                                 }
61                                 else if (m_Direction == -1 && frames < start)
62                                 {
63                                         m_Direction = 1;
64                                         frames = start + (start - frames);
65                                         m_Time = frames / fps;
66                                         didLoop = true;
67                                 }
68                                 else
69                                 {
70                                         // we're within the range, we can stop fixing. We do this in
71                                         // a loop to fix conditions when time has advanced so far
72                                         // that we've ping-ponged back and forth a few times in a
73                                         // single frame. We want to accomodate for this in cases
74                                         // where animations are not advanced on regular intervals.
75                                         break;
76                                 }
77                         }
78                         break;
79         }
80
81         m_DidLoop = didLoop;
82         return keepGoing;
83 }
84
85 void LinearAnimationInstance::time(float value)
86 {
87         if (m_Time == value)
88         {
89                 return;
90         }
91         m_Time = value;
92         m_Direction = 1;
93 }