1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_SVG_ANIMATE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_SVG_ANIMATE_H
18 
19 #include "base/log/log.h"
20 #include "base/memory/ace_type.h"
21 #include "frameworks/core/animation/animator.h"
22 #include "frameworks/core/animation/curve_animation.h"
23 #include "frameworks/core/animation/keyframe_animation.h"
24 
25 namespace OHOS::Ace {
26 
27 enum class Fill {
28     FREEZE,
29     REMOVE,
30 };
31 
32 enum class CalcMode {
33     LINEAR,
34     PACED,
35     DISCRETE,
36     SPLINE,
37 };
38 
39 enum class SvgAnimateType {
40     ANIMATE,
41     MOTION,
42     TRANSFORM,
43 };
44 
45 class SvgAnimate : public AceType {
46     DECLARE_ACE_TYPE(SvgAnimate, AceType);
47 
48 public:
49     SvgAnimate() = default;
50     ~SvgAnimate() override = default;
51 
52     template<typename T>
53     bool CreatePropertyAnimate(
54         std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
55     bool CreateMotionAnimate(std::function<void(double)>&& callback, const RefPtr<Animator>& animator);
56 
57     RefPtr<Curve> GetCurve(const std::string& param = "") const
58     {
59         if (calcMode_ == CalcMode::DISCRETE) {
60             return AceType::MakeRefPtr<StepsCurve>(1, StepsCurvePosition::START);
61         } else if (calcMode_ == CalcMode::PACED) {
62             return Curves::LINEAR;
63         } else if (calcMode_ == CalcMode::SPLINE) {
64             return CubicCurveCreator(param);
65         } else {
66             return Curves::LINEAR;
67         }
68     }
69 
GetFillMode()70     FillMode GetFillMode() const
71     {
72         if (fillMode_ == Fill::FREEZE) {
73             return FillMode::FORWARDS;
74         } else {
75             return FillMode::NONE;
76         }
77     }
78 
CubicCurveCreator(const std::string & paramStr)79     RefPtr<Curve> CubicCurveCreator(const std::string& paramStr) const
80     {
81         std::vector<std::string> params;
82         StringUtils::SplitStr(paramStr, " ", params);
83         if (params.size() != 4) { // 4: the limited number of parameters
84             LOGE("cubic curve accept only 4 parameters");
85             return Curves::LINEAR;
86         }
87         double x1 = StringUtils::StringToDouble(params.at(0));
88         double y1 = StringUtils::StringToDouble(params.at(1));
89         double x2 = StringUtils::StringToDouble(params.at(2));
90         double y2 = StringUtils::StringToDouble(params.at(3));
91         return AceType::MakeRefPtr<CubicCurve>(x1, y1, x2, y2);
92     }
93 
94     template<typename T>
GetStartValue(const T & originalValue)95     T GetStartValue(const T& originalValue) const
96     {
97         if (svgAnimateType_ == SvgAnimateType::TRANSFORM) {
98             return 0.0;
99         }
100 
101         if (!from_.empty()) {
102             return StringUtils::StringToDouble(from_);
103         } else {
104             return originalValue;
105         }
106     }
107 
108     template<>
GetStartValue(const Color & originalValue)109     Color GetStartValue(const Color& originalValue) const
110     {
111         if (!from_.empty()) {
112             return Color::FromString(from_);
113         } else {
114             return originalValue;
115         }
116     }
117 
118     template<>
GetStartValue(const Dimension & originalValue)119     Dimension GetStartValue(const Dimension& originalValue) const
120     {
121         if (!from_.empty()) {
122             return StringUtils::StringToDimension(from_);
123         } else {
124             return originalValue;
125         }
126     }
127 
128     template<typename T>
GetEndValue(const T & startValue)129     T GetEndValue(const T& startValue) const
130     {
131         if (svgAnimateType_ == SvgAnimateType::TRANSFORM) {
132             return 1.0;
133         }
134 
135         if (!to_.empty()) {
136             return StringUtils::StringToDouble(to_);
137         } else if (!by_.empty()) {
138             return startValue + StringUtils::StringToDouble(by_);
139         } else {
140             return startValue;
141         }
142     }
143 
144     template<>
GetEndValue(const Color & startValue)145     Color GetEndValue(const Color& startValue) const
146     {
147         if (!to_.empty()) {
148             return Color::FromString(to_);
149         } else if (!by_.empty()) {
150             return startValue + Color::FromString(by_);
151         } else {
152             return startValue;
153         }
154     }
155 
156     template<>
GetEndValue(const Dimension & startValue)157     Dimension GetEndValue(const Dimension& startValue) const
158     {
159         if (!to_.empty()) {
160             return StringUtils::StringToDimension(to_);
161         } else if (!by_.empty()) {
162             return startValue + StringUtils::StringToDimension(by_);
163         } else {
164             return startValue;
165         }
166     }
167 
168     template<typename T>
GetValue(const std::string & value)169     T GetValue(const std::string& value) const
170     {
171         return StringUtils::StringToDouble(value);
172     }
173 
174     template<>
GetValue(const std::string & value)175     Dimension GetValue(const std::string& value) const
176     {
177         return StringUtils::StringToDimension(value);
178     }
179 
180     template<>
GetValue(const std::string & value)181     Color GetValue(const std::string& value) const
182     {
183         return Color::FromString(value);
184     }
185 
SetAttributeName(const std::string & attributeName)186     void SetAttributeName(const std::string& attributeName)
187     {
188         attributeName_ = attributeName;
189     }
190 
SetBegin(int32_t begin)191     void SetBegin(int32_t begin)
192     {
193         begin_ = begin;
194     }
195 
SetDur(int32_t dur)196     void SetDur(int32_t dur)
197     {
198         dur_ = dur;
199     }
200 
SetEnd(int32_t end)201     void SetEnd(int32_t end)
202     {
203         end_ = end;
204     }
205 
SetRepeatCount(int32_t repeatCount)206     void SetRepeatCount(int32_t repeatCount)
207     {
208         repeatCount_ = repeatCount;
209     }
210 
SetFillMode(Fill fillMode)211     void SetFillMode(Fill fillMode)
212     {
213         fillMode_ = fillMode;
214     }
215 
SetCalcMode(CalcMode calcMode)216     void SetCalcMode(CalcMode calcMode)
217     {
218         calcMode_ = calcMode;
219     }
220 
SetValues(const std::vector<std::string> & values)221     void SetValues(const std::vector<std::string>& values)
222     {
223         if (!values.empty()) {
224             values_.clear();
225             values_.assign(values.begin(), values.end());
226         }
227     }
228 
SetKeyTimes(const std::vector<double> & keyTimes)229     void SetKeyTimes(const std::vector<double>& keyTimes)
230     {
231         if (!keyTimes.empty()) {
232             keyTimes_.clear();
233             keyTimes_.assign(keyTimes.begin(), keyTimes.end());
234         }
235     }
236 
SetKeySplines(const std::vector<std::string> & keySplines)237     void SetKeySplines(const std::vector<std::string>& keySplines)
238     {
239         if (!keySplines.empty()) {
240             keySplines_.clear();
241             keySplines_.assign(keySplines.begin(), keySplines.end());
242         }
243     }
244 
SetFrom(const std::string & from)245     void SetFrom(const std::string& from)
246     {
247         from_ = from;
248     }
249 
SetTo(const std::string & to)250     void SetTo(const std::string& to)
251     {
252         to_ = to;
253     }
254 
SetBy(const std::string & by)255     void SetBy(const std::string& by)
256     {
257         by_ = by;
258     }
259 
GetBegin()260     int32_t GetBegin() const
261     {
262         return std::max(begin_, 0);
263     }
264 
GetDur()265     int32_t GetDur() const
266     {
267         if (dur_ > 0) {
268             return dur_;
269         }
270         return std::max((GetEnd() - GetBegin()), 0);
271     }
272 
GetEnd()273     int32_t GetEnd() const
274     {
275         return std::max(end_, 0);
276     }
277 
GetFrom()278     const std::string& GetFrom() const
279     {
280         return from_;
281     }
282 
GetTo()283     const std::string& GetTo() const
284     {
285         return to_;
286     }
287 
GetBy()288     const std::string& GetBy() const
289     {
290         return by_;
291     }
292 
GetAttributeName()293     const std::string GetAttributeName() const
294     {
295         if (svgAnimateType_ == SvgAnimateType::TRANSFORM) {
296             return attributeName_ + "_" + transformType_;
297         }
298         return attributeName_;
299     }
300 
GetValues()301     const std::vector<std::string>& GetValues() const
302     {
303         return values_;
304     }
305 
GetKeyTimes()306     const std::vector<double>& GetKeyTimes() const
307     {
308         return keyTimes_;
309     }
310 
GetKeySplines()311     const std::vector<std::string>& GetKeySplines() const
312     {
313         return keySplines_;
314     }
315 
GetRepeatCount()316     int32_t GetRepeatCount() const
317     {
318         return repeatCount_;
319     }
320 
GetCalcMode()321     CalcMode GetCalcMode() const
322     {
323         return calcMode_;
324     }
325 
SetKeyPoints(const std::vector<std::string> & keyPoints)326     void SetKeyPoints(const std::vector<std::string>& keyPoints)
327     {
328         if (!keyPoints.empty()) {
329             keyPoints_.clear();
330             keyPoints_.assign(keyPoints.begin(), keyPoints.end());
331         }
332     }
333 
SetPath(const std::string & path)334     void SetPath(const std::string& path)
335     {
336         path_ = path;
337     }
338 
SetRotate(const std::string & rotate)339     void SetRotate(const std::string& rotate)
340     {
341         rotate_ = rotate;
342     }
343 
GetKeyPoints()344     const std::vector<std::string>& GetKeyPoints() const
345     {
346         return keyPoints_;
347     }
348 
GetPath()349     const std::string& GetPath() const
350     {
351         return path_;
352     }
353 
GetRotate()354     const std::string& GetRotate() const
355     {
356         return rotate_;
357     }
358 
SetTransformType(const std::string & transformType)359     void SetTransformType(const std::string& transformType)
360     {
361         transformType_ = transformType;
362     }
363 
GetTransformType()364     const std::string& GetTransformType() const
365     {
366         return transformType_;
367     }
368 
GetSvgAnimateType()369     SvgAnimateType GetSvgAnimateType() const
370     {
371         return svgAnimateType_;
372     }
373 
SetSvgAnimateType(SvgAnimateType svgAnimateType)374     void SetSvgAnimateType(SvgAnimateType svgAnimateType)
375     {
376         svgAnimateType_ = svgAnimateType;
377     }
378 
GetKeyValues()379     const std::vector<std::string>& GetKeyValues() const
380     {
381         if (svgAnimateType_ == SvgAnimateType::MOTION) {
382             return keyPoints_;
383         }
384         return values_;
385     }
386 
Copy(RefPtr<SvgAnimate> & svgAnimate)387     void Copy(RefPtr<SvgAnimate>& svgAnimate)
388     {
389         svgAnimate->SetAttributeName(attributeName_);
390         svgAnimate->SetBegin(begin_);
391         svgAnimate->SetDur(dur_);
392         svgAnimate->SetEnd(end_);
393         svgAnimate->SetRepeatCount(repeatCount_);
394         svgAnimate->SetFillMode(fillMode_);
395         svgAnimate->SetCalcMode(calcMode_);
396         svgAnimate->SetValues(values_);
397         svgAnimate->SetKeyTimes(keyTimes_);
398         svgAnimate->SetKeySplines(keySplines_);
399         svgAnimate->SetFrom(from_);
400         svgAnimate->SetTo(to_);
401         svgAnimate->SetBy(by_);
402         svgAnimate->SetSvgAnimateType(svgAnimateType_);
403         svgAnimate->SetTransformType(transformType_);
404     }
405 
406     bool GetValuesRange(std::vector<float>& from, std::vector<float>& to, std::string& type);
407 
408     bool GetFrames(std::vector<std::vector<float>>& frames, std::string& type);
409 
410 protected:
411     std::string attributeName_;
412     int32_t begin_ = 0;
413     int32_t dur_ = 0;
414     int32_t end_ = 0;
415     int32_t repeatCount_ = 1;
416     Fill fillMode_ = Fill::REMOVE;
417     CalcMode calcMode_ = CalcMode::LINEAR;
418     std::vector<std::string> values_;
419     std::vector<double> keyTimes_;
420     std::vector<std::string> keySplines_;
421     std::string from_;
422     std::string to_;
423     std::string by_;
424 
425     std::vector<std::string> keyPoints_;
426     std::string path_;
427     std::string rotate_;
428 
429     std::string transformType_;
430     SvgAnimateType svgAnimateType_ = SvgAnimateType::ANIMATE;
431 
432 private:
433     template<typename T>
434     void CreateKeyframe(
435         const RefPtr<KeyframeAnimation<T>>& animation, const T& value, float time, const RefPtr<Curve>& curve);
436     template<typename T>
437     void CreateFirstKeyframe(const RefPtr<KeyframeAnimation<T>>& animation, const T& value);
438 
439     template<typename T>
440     bool CreateDiscreteAnimate(
441         std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
442     template<typename T>
443     bool DiscreteAnimate(
444         const RefPtr<KeyframeAnimation<T>>& animation, const T& originalValue, const T& startValue, const T& endValue);
445     template<typename T>
446     bool DiscreteAnimate(const RefPtr<KeyframeAnimation<T>>& animation, const T& originalValue);
447     template<typename T>
448     bool DiscreteWithValues(const RefPtr<KeyframeAnimation<T>>& animation, const T& originalValue);
449     template<typename T>
450     bool DiscreteWithKeyTimes(const RefPtr<KeyframeAnimation<T>>& animation, const T& originalValue);
451 
452     template<typename T>
453     bool CreateLinearAnimate(
454         std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
455     template<typename T>
456     bool LinearAnimateFromTo(
457         std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
458     template<typename T>
459     bool LinearAnimate(const RefPtr<KeyframeAnimation<T>>& animation);
460     template<typename T>
461     bool LinearWithKeyTimes(const RefPtr<KeyframeAnimation<T>>& animation);
462     template<typename T>
463     bool LinearWithValues(const RefPtr<KeyframeAnimation<T>>& animation);
464 
465     template<typename T>
466     bool CreatePacedAnimate(
467         std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
468 
469     template<typename T>
470     bool CreateSplineAnimate(
471         std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
472     template<typename T>
473     bool SplineAnimate(std::function<void(T)>&& callback, const T& originalValue, const RefPtr<Animator>& animator);
474     template<typename T>
475     bool SplineAnimate(const RefPtr<KeyframeAnimation<T>>& animation);
476     template<typename T>
477     bool SplineWithKeySplines(const RefPtr<KeyframeAnimation<T>>& animation);
478     template<typename T>
479     bool SplineWithKeyTimes(const RefPtr<KeyframeAnimation<T>>& animation);
480 };
481 
482 } // namespace OHOS::Ace
483 
484 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_SVG_ANIMATE_H
485