• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "bridge/declarative_frontend/jsview/js_image_animator.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/view_stack_processor.h"
20 #include "core/components_ng/pattern/image_animator/image_animator_view.h"
21 
22 namespace OHOS::Ace::Framework {
23 
24 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
25 constexpr uint32_t DEFAULT_ITERATIONS = 1;
26 constexpr FillMode DEFAULT_FILL_MODE = FillMode::FORWARDS;
27 
Create()28 void JSImageAnimator::Create()
29 {
30     if (Container::IsCurrentUseNewPipeline()) {
31         NG::ImageAnimatorView::Create();
32         return;
33     }
34     RefPtr<ImageAnimatorComponent> imageAnimator = AceType::MakeRefPtr<ImageAnimatorComponent>("ImageAnimator");
35     imageAnimator->SetIteration(DEFAULT_ITERATIONS);
36     imageAnimator->SetDuration(DEFAULT_DURATION);
37     ViewStackProcessor::GetInstance()->Push(imageAnimator);
38     // Init Common Styles for ImageAnimator
39     ViewStackProcessor::GetInstance()->GetBoxComponent();
40 }
41 
JSBind(BindingTarget globalObj)42 void JSImageAnimator::JSBind(BindingTarget globalObj)
43 {
44     JSClass<JSImageAnimator>::Declare("ImageAnimator");
45     MethodOptions opt = MethodOptions::NONE;
46     JSClass<JSImageAnimator>::StaticMethod("create", &JSImageAnimator::Create, opt);
47     JSClass<JSImageAnimator>::StaticMethod("images", &JSImageAnimator::SetImages, opt);
48     JSClass<JSImageAnimator>::StaticMethod("state", &JSImageAnimator::SetState, opt);
49     JSClass<JSImageAnimator>::StaticMethod("duration", &JSImageAnimator::SetDuration, opt);
50     JSClass<JSImageAnimator>::StaticMethod("iterations", &JSImageAnimator::SetIteration, opt);
51     JSClass<JSImageAnimator>::StaticMethod("reverse", &JSImageAnimator::SetIsReverse, opt);
52     JSClass<JSImageAnimator>::StaticMethod("fixedSize", &JSImageAnimator::SetFixedSize, opt);
53     JSClass<JSImageAnimator>::StaticMethod("fillMode", &JSImageAnimator::SetFillMode, opt);
54     JSClass<JSImageAnimator>::StaticMethod("preDecode", &JSImageAnimator::SetPreDecode, opt);
55 
56     JSClass<JSImageAnimator>::StaticMethod("onStart", &JSImageAnimator::OnStart, opt);
57     JSClass<JSImageAnimator>::StaticMethod("onPause", &JSImageAnimator::OnPause, opt);
58     JSClass<JSImageAnimator>::StaticMethod("onRepeat", &JSImageAnimator::OnRepeat, opt);
59     JSClass<JSImageAnimator>::StaticMethod("onCancel", &JSImageAnimator::OnCancel, opt);
60     JSClass<JSImageAnimator>::StaticMethod("onFinish", &JSImageAnimator::OnFinish, opt);
61 
62     JSClass<JSImageAnimator>::Inherit<JSContainerBase>();
63     JSClass<JSImageAnimator>::Inherit<JSViewAbstract>();
64     JSClass<JSImageAnimator>::Bind<>(globalObj);
65 }
66 
SetImages(const JSCallbackInfo & info)67 void JSImageAnimator::SetImages(const JSCallbackInfo& info)
68 {
69     if (info.Length() < 1) {
70         LOGE("JSImageAnimator: The arg is wrong, it is supposed to have one object argument.");
71         return;
72     }
73     if (info[0]->IsNull()) {
74         LOGE("JSImageAnimator: info is null.");
75         return;
76     }
77     if (!info[0]->IsArray()) {
78         LOGE("JSImageAnimator: info is not array.");
79         return;
80     }
81     JSRef<JSArray> imageArray = JSRef<JSArray>::Cast(info[0]);
82     std::vector<ImageProperties> images;
83     for (uint32_t i = 0; i < imageArray->Length(); ++i) {
84         ImageProperties imageProperties;
85         ParseImages(imageArray->GetValueAt(i), imageProperties);
86         images.push_back(imageProperties);
87     }
88 
89     if (Container::IsCurrentUseNewPipeline()) {
90         NG::ImageAnimatorView::SetImages(std::move(images));
91         return;
92     }
93 
94     auto imageAnimator =
95         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
96     if (imageAnimator) {
97         imageAnimator->SetImageProperties(images);
98     }
99 }
100 
SetState(int32_t state)101 void JSImageAnimator::SetState(int32_t state)
102 {
103     if (state < static_cast<int32_t>(Animator::Status::IDLE) ||
104         state > static_cast<int32_t>(Animator::Status::STOPPED)) {
105         LOGW("ImageAnimator SetState %{public}d, invalid, use default AnimationStatus.Initial", state);
106         state = static_cast<int32_t>(Animator::Status::IDLE);
107     }
108     if (Container::IsCurrentUseNewPipeline()) {
109         NG::ImageAnimatorView::SetStatus(static_cast<Animator::Status>(state));
110         return;
111     }
112     auto imageAnimator =
113         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
114     if (imageAnimator) {
115         imageAnimator->SetStatus(static_cast<Animator::Status>(state));
116     }
117 }
118 
SetDuration(int32_t duration)119 void JSImageAnimator::SetDuration(int32_t duration)
120 {
121     if (duration < 0) {
122         LOGW("ImageAnimator SetDuration %{public}d, invalid, use default %{public}d", duration, DEFAULT_DURATION);
123         duration = DEFAULT_DURATION;
124     }
125     if (Container::IsCurrentUseNewPipeline()) {
126         NG::ImageAnimatorView::SetDuration(duration);
127         return;
128     }
129     auto imageAnimator =
130         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
131     if (imageAnimator) {
132         imageAnimator->SetDuration(duration);
133     }
134 }
135 
SetIteration(int32_t iteration)136 void JSImageAnimator::SetIteration(int32_t iteration)
137 {
138     if (iteration < -1) {
139         LOGW("ImageAnimator SetIteration %{public}d, invalid, use default %{public}d", iteration, DEFAULT_ITERATIONS);
140         iteration = DEFAULT_ITERATIONS;
141     }
142     if (Container::IsCurrentUseNewPipeline()) {
143         NG::ImageAnimatorView::SetIteration(iteration);
144         return;
145     }
146     auto imageAnimator =
147         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
148     if (imageAnimator) {
149         imageAnimator->SetIteration(iteration);
150     }
151 }
152 
SetFillMode(int32_t fillMode)153 void JSImageAnimator::SetFillMode(int32_t fillMode)
154 {
155     if (fillMode < static_cast<int32_t>(FillMode::NONE) || fillMode > static_cast<int32_t>(FillMode::BOTH)) {
156         LOGW("ImageAnimator SetFillMode %{public}d, invalid, use default %{public}d", fillMode,
157             static_cast<int32_t>(DEFAULT_FILL_MODE));
158         fillMode = static_cast<int32_t>(DEFAULT_FILL_MODE);
159     }
160     if (Container::IsCurrentUseNewPipeline()) {
161         NG::ImageAnimatorView::SetFillMode(static_cast<FillMode>(fillMode));
162         return;
163     }
164     auto imageAnimator =
165         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
166     if (imageAnimator) {
167         imageAnimator->SetFillMode(static_cast<FillMode>(fillMode));
168     }
169 }
170 
SetPreDecode(int32_t preDecode)171 void JSImageAnimator::SetPreDecode(int32_t preDecode)
172 {
173     if (Container::IsCurrentUseNewPipeline()) {
174         NG::ImageAnimatorView::SetPreDecode(preDecode);
175         return;
176     }
177     auto imageAnimator =
178         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
179     if (imageAnimator) {
180         imageAnimator->SetPreDecode(preDecode);
181     }
182 }
183 
SetIsReverse(bool isReverse)184 void JSImageAnimator::SetIsReverse(bool isReverse)
185 {
186     if (Container::IsCurrentUseNewPipeline()) {
187         NG::ImageAnimatorView::SetIsReverse(isReverse);
188         return;
189     }
190     auto imageAnimator =
191         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
192     if (imageAnimator) {
193         imageAnimator->SetIsReverse(isReverse);
194     }
195 }
196 
SetFixedSize(bool fixedSize)197 void JSImageAnimator::SetFixedSize(bool fixedSize)
198 {
199     if (Container::IsCurrentUseNewPipeline()) {
200         NG::ImageAnimatorView::SetFixedSize(fixedSize);
201         return;
202     }
203     auto imageAnimator =
204         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
205     if (imageAnimator) {
206         imageAnimator->SetIsFixedSize(fixedSize);
207     }
208 }
209 
OnStart(const JSCallbackInfo & info)210 void JSImageAnimator::OnStart(const JSCallbackInfo& info)
211 {
212     if (Container::IsCurrentUseNewPipeline()) {
213         NG::ImageAnimatorView::SetImageAnimatorEvent(GetAnimatorEvent(info), NG::AnimatorEventType::ON_START);
214         return;
215     }
216     auto imageAnimator =
217         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
218     if (!imageAnimator) {
219         return;
220     }
221     const auto& controller = imageAnimator->GetImageAnimatorController();
222     if (controller) {
223         auto startEvent = GetEventMarker(info);
224         controller->SetStartEvent(startEvent);
225     }
226 }
227 
OnPause(const JSCallbackInfo & info)228 void JSImageAnimator::OnPause(const JSCallbackInfo& info)
229 {
230     if (Container::IsCurrentUseNewPipeline()) {
231         NG::ImageAnimatorView::SetImageAnimatorEvent(GetAnimatorEvent(info), NG::AnimatorEventType::ON_PAUSE);
232         return;
233     }
234     auto imageAnimator =
235         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
236     if (!imageAnimator) {
237         return;
238     }
239     const auto& controller = imageAnimator->GetImageAnimatorController();
240     if (controller) {
241         auto pauseEvent = GetEventMarker(info);
242         controller->SetPauseEvent(pauseEvent);
243     }
244 }
245 
OnRepeat(const JSCallbackInfo & info)246 void JSImageAnimator::OnRepeat(const JSCallbackInfo& info)
247 {
248     if (Container::IsCurrentUseNewPipeline()) {
249         NG::ImageAnimatorView::SetImageAnimatorEvent(GetAnimatorEvent(info), NG::AnimatorEventType::ON_REPEAT);
250         return;
251     }
252     auto imageAnimator =
253         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
254     if (!imageAnimator) {
255         return;
256     }
257     const auto& controller = imageAnimator->GetImageAnimatorController();
258     if (controller) {
259         auto repeatEvent = GetEventMarker(info);
260         controller->SetRepeatEvent(repeatEvent);
261     }
262 }
263 
OnCancel(const JSCallbackInfo & info)264 void JSImageAnimator::OnCancel(const JSCallbackInfo& info)
265 {
266     if (Container::IsCurrentUseNewPipeline()) {
267         NG::ImageAnimatorView::SetImageAnimatorEvent(GetAnimatorEvent(info), NG::AnimatorEventType::ON_CANCEL);
268         return;
269     }
270     auto imageAnimator =
271         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
272     if (!imageAnimator) {
273         return;
274     }
275     const auto& controller = imageAnimator->GetImageAnimatorController();
276     if (controller) {
277         auto cancelEvent = GetEventMarker(info);
278         controller->SetCancelEvent(cancelEvent);
279     }
280 }
281 
OnFinish(const JSCallbackInfo & info)282 void JSImageAnimator::OnFinish(const JSCallbackInfo& info)
283 {
284     if (Container::IsCurrentUseNewPipeline()) {
285         NG::ImageAnimatorView::SetImageAnimatorEvent(GetAnimatorEvent(info), NG::AnimatorEventType::ON_FINISH);
286         return;
287     }
288     auto imageAnimator =
289         AceType::DynamicCast<ImageAnimatorComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
290     if (!imageAnimator) {
291         return;
292     }
293     const auto& controller = imageAnimator->GetImageAnimatorController();
294     if (controller) {
295         auto finishEvent = GetEventMarker(info);
296         controller->SetStopEvent(finishEvent);
297     }
298 }
299 
GetEventMarker(const JSCallbackInfo & info)300 EventMarker JSImageAnimator::GetEventMarker(const JSCallbackInfo& info)
301 {
302     if (!info[0]->IsFunction()) {
303         LOGE("info[0] is not a function.");
304         return {};
305     }
306     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
307     auto eventMarker = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc)]() {
308         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
309         ACE_SCORING_EVENT("ImageAnimator.onClick");
310         func->Execute();
311     });
312     return eventMarker;
313 }
314 
GetAnimatorEvent(const JSCallbackInfo & info)315 AnimatorEvent JSImageAnimator::GetAnimatorEvent(const JSCallbackInfo& info)
316 {
317     if (!info[0]->IsFunction()) {
318         LOGE("info[0] is not a function.");
319         return {};
320     }
321     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
322     auto animatorEvent = [func = std::move(jsFunc)]() { func->Execute(); };
323     return animatorEvent;
324 }
325 
ParseImages(const JSRef<JSVal> & image,ImageProperties & imageProperties)326 void JSImageAnimator::ParseImages(const JSRef<JSVal>& image, ImageProperties& imageProperties)
327 {
328     if (!image->IsObject()) {
329         LOGE("image is not Object.");
330         return;
331     }
332     JSRef<JSObject> jsObjImage = JSRef<JSObject>::Cast(image);
333     if (!ParseJsMedia(jsObjImage->GetProperty("src"), imageProperties.src)) {
334         LOGE("parse image property src failed!");
335     }
336     ParseJsDimensionVp(jsObjImage->GetProperty("width"), imageProperties.width);
337     ParseJsDimensionVp(jsObjImage->GetProperty("height"), imageProperties.height);
338     ParseJsDimensionVp(jsObjImage->GetProperty("top"), imageProperties.top);
339     ParseJsDimensionVp(jsObjImage->GetProperty("left"), imageProperties.left);
340     ParseJsInt32(jsObjImage->GetProperty("duration"), imageProperties.duration);
341 }
342 
343 } // namespace OHOS::Ace::Framework
344