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 #include "frameworks/bridge/common/utils/transform_convertor.h"
17
18 #include <algorithm>
19
20 #include "base/utils/string_utils.h"
21 #include "frameworks/bridge/common/dom/dom_type.h"
22
23 namespace OHOS::Ace {
24 namespace {
25
26 constexpr int32_t PARAM_SINGLE = 1;
27 constexpr int32_t PARAM_DOUBLE = 2;
28 constexpr int32_t PARAM_THREE = 3;
29 constexpr int32_t PARAM_FOUR = 4;
30 constexpr int32_t PARAM_SIX = 6;
31 constexpr int32_t PARAM_SIXTEEN = 16;
32
33 } // namespace
34
35 const std::vector<std::string> TransformConvertor::TransformKey = {
36 DOM_TRANSLATE,
37 DOM_TRANSLATE_3D,
38 DOM_TRANSLATE_X,
39 DOM_TRANSLATE_Y,
40 DOM_TRANSLATE_Z,
41 DOM_ROTATE,
42 DOM_ROTATE_3D,
43 DOM_ROTATE_X,
44 DOM_ROTATE_Y,
45 DOM_ROTATE_Z,
46 DOM_SCALE,
47 DOM_SCALE_3D,
48 DOM_SCALE_X,
49 DOM_SCALE_Y,
50 DOM_SCALE_Z,
51 DOM_SKEW,
52 DOM_SKEW_X,
53 DOM_SKEW_Y,
54 DOM_MATRIX,
55 DOM_MATRIX_3D,
56 DOM_PERSPECTIVE,
57 };
58
Convert(const std::string & key,const std::string & value,double time)59 void TransformConvertor::Convert(const std::string& key, const std::string& value, double time)
60 {
61 auto iter = TransformConvertorMap.find(key);
62 if (iter != TransformConvertorMap.end()) {
63 iter->second(value, time, *this);
64 }
65 }
66
InsertIdentityKeyframe(double time)67 void TransformConvertor::InsertIdentityKeyframe(double time)
68 {
69 noneKeyframeTimes_.push_back(static_cast<float>(time));
70 }
71
AddAnimationToTweenOption(TweenOption & option) const72 void TransformConvertor::AddAnimationToTweenOption(TweenOption& option) const
73 {
74 auto noneKeyframes = std::list<RefPtr<Keyframe<TransformOperation>>>();
75 TransformOperation operation;
76 operation.type_ = TransformOperationType::UNDEFINED;
77 for (float time : noneKeyframeTimes_) {
78 noneKeyframes.push_back(AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation));
79 }
80 for (const auto& animation : operationList_) {
81 if (!noneKeyframes.empty()) {
82 // insert transform: none keyframe into animation
83 animation->AddKeyframe(noneKeyframes);
84 }
85 option.AddTransformAnimation(animation);
86 }
87 }
88
ApplyCurve(const RefPtr<Curve> & curve)89 void TransformConvertor::ApplyCurve(const RefPtr<Curve>& curve)
90 {
91 for (const auto& animation : operationList_) {
92 if (animation) {
93 animation->SetCurve(curve);
94 }
95 }
96 }
97
ClearAnimations()98 void TransformConvertor::ClearAnimations()
99 {
100 operationList_.clear();
101 operationMap_.clear();
102 noneKeyframeTimes_.clear();
103 }
104
AddKeyframe(AnimationType type,const RefPtr<Keyframe<TransformOperation>> & keyframe)105 void TransformConvertor::AddKeyframe(AnimationType type, const RefPtr<Keyframe<TransformOperation>>& keyframe)
106 {
107 auto& animation = operationMap_[type];
108 if (!animation) {
109 animation = AceType::MakeRefPtr<KeyframeAnimation<TransformOperation>>();
110 operationList_.push_back(animation);
111 }
112 animation->AddKeyframe(keyframe);
113 }
114
AddKeyframe(AnimationType type,double time,const TranslateOperation & translate)115 void TransformConvertor::AddKeyframe(AnimationType type, double time, const TranslateOperation& translate)
116 {
117 TransformOperation operation;
118 operation.type_ = TransformOperationType::TRANSLATE;
119 operation.translateOperation_ = translate;
120 auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
121 AddKeyframe(type, keyframe);
122 }
123
AddKeyframe(AnimationType type,double time,const SkewOperation & skew)124 void TransformConvertor::AddKeyframe(AnimationType type, double time, const SkewOperation& skew)
125 {
126 TransformOperation operation;
127 operation.type_ = TransformOperationType::SKEW;
128 operation.skewOperation_ = skew;
129 auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
130 AddKeyframe(type, keyframe);
131 }
132
AddKeyframe(AnimationType type,double time,const ScaleOperation & scale)133 void TransformConvertor::AddKeyframe(AnimationType type, double time, const ScaleOperation& scale)
134 {
135 TransformOperation operation;
136 operation.type_ = TransformOperationType::SCALE;
137 operation.scaleOperation_ = scale;
138 auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
139 AddKeyframe(type, keyframe);
140 }
141
AddKeyframe(AnimationType type,double time,const RotateOperation & rotate)142 void TransformConvertor::AddKeyframe(AnimationType type, double time, const RotateOperation& rotate)
143 {
144 TransformOperation operation;
145 operation.type_ = TransformOperationType::ROTATE;
146 operation.rotateOperation_ = rotate;
147 auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
148 AddKeyframe(type, keyframe);
149 }
150
AddKeyframe(AnimationType type,double time,const Matrix4 & matrix)151 void TransformConvertor::AddKeyframe(AnimationType type, double time, const Matrix4& matrix)
152 {
153 TransformOperation operation;
154 operation.type_ = TransformOperationType::MATRIX;
155 operation.matrix4_ = matrix;
156 auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
157 AddKeyframe(type, keyframe);
158 }
159
AddKeyframe(AnimationType type,double time,const PerspectiveOperation & distance)160 void TransformConvertor::AddKeyframe(AnimationType type, double time, const PerspectiveOperation& distance)
161 {
162 TransformOperation operation;
163 operation.type_ = TransformOperationType::PERSPECTIVE;
164 operation.perspectiveOperation_ = distance;
165 auto keyframe = AceType::MakeRefPtr<Keyframe<TransformOperation>>(time, operation);
166 AddKeyframe(type, keyframe);
167 }
168
169 const std::unordered_map<std::string, void (*)(const std::string&, const double&, TransformConvertor&)>
170 TransformConvertor::TransformConvertorMap = {
171 { DOM_TRANSLATE,
__anonbf1309590202() 172 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
173 std::vector<std::string> offsets;
174 StringUtils::StringSplitter(typeValue, ' ', offsets);
175 if (offsets.size() == PARAM_DOUBLE) {
176 auto dx = StringUtils::StringToDimension(offsets[0]);
177 auto dy = StringUtils::StringToDimension(offsets[1]);
178 convertor.AddKeyframe(AnimationType::TRANSLATE, time, TranslateOperation(dx, dy, Dimension {}));
179 } else if (offsets.size() == PARAM_SINGLE) {
180 auto dx = StringUtils::StringToDimension(offsets[0]);
181 convertor.AddKeyframe(AnimationType::TRANSLATE, time, TranslateOperation(dx, Dimension {}));
182 }
183 } },
184 { DOM_TRANSLATE_X,
__anonbf1309590302() 185 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
186 auto dx = StringUtils::StringToDimension(typeValue);
187 convertor.AddKeyframe(AnimationType::TRANSLATE_X, time, TranslateOperation(dx, Dimension {}));
188 } },
189 { DOM_TRANSLATE_Y,
__anonbf1309590402() 190 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
191 auto dy = StringUtils::StringToDimension(typeValue);
192 convertor.AddKeyframe(AnimationType::TRANSLATE_Y, time, TranslateOperation(Dimension {}, dy));
193 } },
194 { DOM_TRANSLATE_Z,
__anonbf1309590502() 195 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
196 auto dz = StringUtils::StringToDimension(typeValue);
197
198 convertor.AddKeyframe(
199 AnimationType::TRANSLATE_Z, time, TranslateOperation(Dimension {}, Dimension {}, dz));
200 } },
201 { DOM_TRANSLATE_3D,
__anonbf1309590602() 202 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
203 std::vector<std::string> offsets;
204 StringUtils::StringSplitter(typeValue, ' ', offsets);
205 if (offsets.size() == PARAM_THREE) {
206 auto dx = StringUtils::StringToDimension(offsets[0]);
207 auto dy = StringUtils::StringToDimension(offsets[1]);
208 auto dz = StringUtils::StringToDimension(offsets[2]);
209
210 convertor.AddKeyframe(AnimationType::TRANSLATE_3D, time, TranslateOperation(dx, dy, dz));
211 }
212 } },
213 { DOM_ROTATE_3D,
__anonbf1309590702() 214 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
215 std::vector<std::string> offsets;
216 StringUtils::StringSplitter(typeValue, ' ', offsets);
217 if (offsets.size() == PARAM_FOUR) {
218 auto dx = static_cast<float>(StringUtils::StringToDouble(offsets[0]));
219 auto dy = static_cast<float>(StringUtils::StringToDouble(offsets[1]));
220 auto dz = static_cast<float>(StringUtils::StringToDouble(offsets[2]));
221 auto degree = StringUtils::StringToDegree(offsets[3]);
222 convertor.AddKeyframe(
223 AnimationType::ROTATE_3D, time, RotateOperation { dx, dy, dz, static_cast<float>(degree) });
224 }
225 } },
226 { DOM_ROTATE,
__anonbf1309590802() 227 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
228 auto degree = StringUtils::StringToDegree(typeValue);
229 convertor.AddKeyframe(
230 AnimationType::ROTATE, time, RotateOperation { 0, 0, 1, static_cast<float>(degree) });
231 } },
232 { DOM_ROTATE_X,
__anonbf1309590902() 233 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
234 auto degree = StringUtils::StringToDegree(typeValue);
235 convertor.AddKeyframe(
236 AnimationType::ROTATE_X, time, RotateOperation { 1, 0, 0, static_cast<float>(degree) });
237 } },
238 { DOM_ROTATE_Y,
__anonbf1309590a02() 239 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
240 auto degree = StringUtils::StringToDegree(typeValue);
241 convertor.AddKeyframe(
242 AnimationType::ROTATE_Y, time, RotateOperation { 0, 1, 0, static_cast<float>(degree) });
243 } },
244 { DOM_ROTATE_Z,
__anonbf1309590b02() 245 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
246 auto degree = StringUtils::StringToDegree(typeValue);
247 convertor.AddKeyframe(
248 AnimationType::ROTATE_Z, time, RotateOperation { 0, 0, 1, static_cast<float>(degree) });
249 } },
250 { DOM_SCALE,
__anonbf1309590c02() 251 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
252 if (typeValue.find(' ') != std::string::npos) {
253 std::vector<std::string> values;
254 StringUtils::StringSplitter(typeValue, ' ', values);
255 if (values.size() == PARAM_DOUBLE) {
256 double scaleValueX = StringUtils::StringToDouble(values[0]);
257 double scaleValueY = StringUtils::StringToDouble(values[1]);
258 convertor.AddKeyframe(
259 AnimationType::SCALE, time, ScaleOperation(scaleValueX, scaleValueY, 1.0f));
260 }
261 } else {
262 auto scale = static_cast<float>(StringUtils::StringToDouble(typeValue));
263 convertor.AddKeyframe(AnimationType::SCALE, time, ScaleOperation(scale, scale, 1.0f));
264 }
265 } },
266 { DOM_SCALE_X,
__anonbf1309590d02() 267 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
268 auto scaleX = static_cast<float>(StringUtils::StringToDouble(typeValue));
269 convertor.AddKeyframe(AnimationType::SCALE_X, time, ScaleOperation(scaleX, 1.0f, 1.0f));
270 } },
271 { DOM_SCALE_Y,
__anonbf1309590e02() 272 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
273 auto scaleY = static_cast<float>(StringUtils::StringToDouble(typeValue));
274 convertor.AddKeyframe(AnimationType::SCALE_Y, time, ScaleOperation(1.0f, scaleY, 1.0f));
275 } },
276 { DOM_SCALE_Z,
__anonbf1309590f02() 277 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
278 auto scaleZ = static_cast<float>(StringUtils::StringToDouble(typeValue));
279 convertor.AddKeyframe(AnimationType::SCALE_Z, time, ScaleOperation(1.0f, 1.0f, scaleZ));
280 } },
281 { DOM_SCALE_3D,
__anonbf1309591002() 282 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
283 std::vector<std::string> offsets;
284 StringUtils::StringSplitter(typeValue, ' ', offsets);
285 if (offsets.size() == PARAM_THREE) {
286 auto scaleX = static_cast<float>(StringUtils::StringToDouble(offsets[0]));
287 auto scaleY = static_cast<float>(StringUtils::StringToDouble(offsets[1]));
288 auto scaleZ = static_cast<float>(StringUtils::StringToDouble(offsets[2]));
289 convertor.AddKeyframe(AnimationType::SCALE_3D, time, ScaleOperation(scaleX, scaleY, scaleZ));
290 }
291 } },
292 { DOM_SKEW,
__anonbf1309591102() 293 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
294 std::vector<std::string> offsets;
295 StringUtils::StringSplitter(typeValue, ' ', offsets);
296 if (offsets.size() == PARAM_DOUBLE) {
297 auto degreeX = static_cast<float>(StringUtils::StringToDegree(offsets[0]));
298 auto degreeY = static_cast<float>(StringUtils::StringToDegree(offsets[1]));
299 convertor.AddKeyframe(AnimationType::SKEW, time, SkewOperation { degreeX, degreeY });
300 } else if (offsets.size() == PARAM_SINGLE) {
301 auto degreeX = static_cast<float>(StringUtils::StringToDegree(typeValue));
302 convertor.AddKeyframe(AnimationType::SKEW, time, SkewOperation { degreeX, 0.0f });
303 }
304 } },
305 { DOM_SKEW_X,
__anonbf1309591202() 306 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
307 auto degreeX = static_cast<float>(StringUtils::StringToDegree(typeValue));
308 convertor.AddKeyframe(AnimationType::SKEW_X, time, SkewOperation { degreeX, 0.0f });
309 } },
310 { DOM_SKEW_Y,
__anonbf1309591302() 311 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
312 auto degreeY = static_cast<float>(StringUtils::StringToDegree(typeValue));
313 convertor.AddKeyframe(AnimationType::SKEW_Y, time, SkewOperation { 0.0f, degreeY });
314 } },
315 { DOM_MATRIX_3D,
__anonbf1309591402() 316 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
317 std::vector<std::string> offsets;
318 StringUtils::StringSplitter(typeValue, ' ', offsets);
319 if (offsets.size() == PARAM_SIXTEEN) {
320 std::vector<double> matrix;
321 for (const auto& offset : offsets) {
322 matrix.push_back(StringUtils::StringToDouble(offset));
323 }
324 Matrix4 m(matrix[0], matrix[4], matrix[8], matrix[12],
325 matrix[1], matrix[5], matrix[9], matrix[13],
326 matrix[2], matrix[6], matrix[10], matrix[14],
327 matrix[3], matrix[7], matrix[11], matrix[15]);
328 convertor.AddKeyframe(AnimationType::MATRIX_3D, time, m);
329 }
330 } },
331 { DOM_MATRIX,
__anonbf1309591502() 332 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
333 std::vector<std::string> offsets;
334 StringUtils::StringSplitter(typeValue, ' ', offsets);
335 if (offsets.size() == PARAM_SIX) {
336 double scaleX = StringUtils::StringToDouble(offsets[0]);
337 double skewY = StringUtils::StringToDouble(offsets[1]);
338 double skewX = StringUtils::StringToDouble(offsets[2]);
339 double scaleY = StringUtils::StringToDouble(offsets[3]);
340 double translateX = StringUtils::StringToDouble(offsets[4]);
341 double translateY = StringUtils::StringToDouble(offsets[5]);
342 Matrix4 matrix = Matrix4::CreateMatrix2D(scaleX, skewY, skewX, scaleY, translateX, translateY);
343 convertor.AddKeyframe(AnimationType::MATRIX_2D, time, matrix);
344 }
345 } },
346 { DOM_PERSPECTIVE,
__anonbf1309591602() 347 [](const std::string& typeValue, const double& time, TransformConvertor& convertor) {
348 auto distance = StringUtils::StringToDimension(typeValue);
349 convertor.AddKeyframe(AnimationType::PERSPECTIVE, time, PerspectiveOperation(distance));
350 } },
351 };
352
353 } // namespace OHOS::Ace
354