• 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/jsview/models/image_animator_model_impl.h"
20 #include "core/components_ng/pattern/image_animator/image_animator_model_ng.h"
21 
22 namespace OHOS::Ace {
23 std::unique_ptr<ImageAnimatorModel> ImageAnimatorModel::instance_ = nullptr;
24 std::mutex ImageAnimatorModel::mutex_;
GetInstance()25 ImageAnimatorModel* ImageAnimatorModel::GetInstance()
26 {
27     if (!instance_) {
28         std::lock_guard<std::mutex> lock(mutex_);
29         if (!instance_) {
30 #ifdef NG_BUILD
31             instance_.reset(new NG::ImageAnimatorModelNG());
32 #else
33             if (Container::IsCurrentUseNewPipeline()) {
34                 instance_.reset(new NG::ImageAnimatorModelNG());
35             } else {
36                 instance_.reset(new Framework::ImageAnimatorModelImpl());
37             }
38 #endif
39         }
40     }
41     return instance_.get();
42 }
43 
44 } // namespace OHOS::Ace
45 
46 namespace OHOS::Ace::Framework {
47 
48 constexpr uint32_t DEFAULT_DURATION = 1000; // ms
49 constexpr uint32_t DEFAULT_ITERATIONS = 1;
50 constexpr FillMode DEFAULT_FILL_MODE = FillMode::FORWARDS;
51 
Create()52 void JSImageAnimator::Create()
53 {
54     ImageAnimatorModel::GetInstance()->Create();
55 }
56 
JSBind(BindingTarget globalObj)57 void JSImageAnimator::JSBind(BindingTarget globalObj)
58 {
59     JSClass<JSImageAnimator>::Declare("ImageAnimator");
60     MethodOptions opt = MethodOptions::NONE;
61     JSClass<JSImageAnimator>::StaticMethod("create", &JSImageAnimator::Create, opt);
62     JSClass<JSImageAnimator>::StaticMethod("images", &JSImageAnimator::SetImages, opt);
63     JSClass<JSImageAnimator>::StaticMethod("state", &JSImageAnimator::SetState, opt);
64     JSClass<JSImageAnimator>::StaticMethod("duration", &JSImageAnimator::SetDuration, opt);
65     JSClass<JSImageAnimator>::StaticMethod("iterations", &JSImageAnimator::SetIteration, opt);
66     JSClass<JSImageAnimator>::StaticMethod("reverse", &JSImageAnimator::SetIsReverse, opt);
67     JSClass<JSImageAnimator>::StaticMethod("fixedSize", &JSImageAnimator::SetFixedSize, opt);
68     JSClass<JSImageAnimator>::StaticMethod("fillMode", &JSImageAnimator::SetFillMode, opt);
69     JSClass<JSImageAnimator>::StaticMethod("preDecode", &JSImageAnimator::SetPreDecode, opt);
70 
71     JSClass<JSImageAnimator>::StaticMethod("onStart", &JSImageAnimator::OnStart, opt);
72     JSClass<JSImageAnimator>::StaticMethod("onPause", &JSImageAnimator::OnPause, opt);
73     JSClass<JSImageAnimator>::StaticMethod("onRepeat", &JSImageAnimator::OnRepeat, opt);
74     JSClass<JSImageAnimator>::StaticMethod("onCancel", &JSImageAnimator::OnCancel, opt);
75     JSClass<JSImageAnimator>::StaticMethod("onFinish", &JSImageAnimator::OnFinish, opt);
76     JSClass<JSImageAnimator>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
77     JSClass<JSImageAnimator>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
78     JSClass<JSImageAnimator>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
79 
80     JSClass<JSImageAnimator>::InheritAndBind<JSContainerBase>(globalObj);
81 }
82 
SetImages(const JSCallbackInfo & info)83 void JSImageAnimator::SetImages(const JSCallbackInfo& info)
84 {
85     if (info.Length() < 1) {
86         return;
87     }
88     if (info[0]->IsNull()) {
89         return;
90     }
91     if (!info[0]->IsArray()) {
92         return;
93     }
94     JSRef<JSArray> imageArray = JSRef<JSArray>::Cast(info[0]);
95     std::vector<ImageProperties> images;
96     for (uint32_t i = 0; i < imageArray->Length(); ++i) {
97         ImageProperties imageProperties;
98         ParseImages(imageArray->GetValueAt(i), imageProperties);
99         images.push_back(imageProperties);
100     }
101 
102     ImageAnimatorModel::GetInstance()->SetImages(images);
103 }
104 
SetState(const JSCallbackInfo & info)105 void JSImageAnimator::SetState(const JSCallbackInfo& info)
106 {
107     if (info.Length() < 1) {
108         return;
109     }
110     int32_t state = static_cast<int32_t>(Animator::Status::IDLE);
111     if (info[0]->IsNumber()) {
112         state = info[0]->ToNumber<int32_t>();
113         if (state < static_cast<int32_t>(Animator::Status::IDLE) ||
114             state > static_cast<int32_t>(Animator::Status::STOPPED)) {
115             state = static_cast<int32_t>(Animator::Status::IDLE);
116         }
117     }
118 
119     ImageAnimatorModel::GetInstance()->SetState(state);
120 }
121 
SetDuration(const JSCallbackInfo & info)122 void JSImageAnimator::SetDuration(const JSCallbackInfo& info)
123 {
124     if (info.Length() < 1) {
125         return;
126     }
127     int32_t duration = DEFAULT_DURATION;
128     if (info[0]->IsNumber()) {
129         duration = info[0]->ToNumber<int32_t>();
130         if (duration < 0) {
131             duration = DEFAULT_DURATION;
132         }
133     }
134 
135     ImageAnimatorModel::GetInstance()->SetDuration(duration);
136 }
137 
SetIteration(const JSCallbackInfo & info)138 void JSImageAnimator::SetIteration(const JSCallbackInfo& info)
139 {
140     if (info.Length() < 1) {
141         return;
142     }
143     int32_t iteration = DEFAULT_ITERATIONS;
144     if (info[0]->IsNumber()) {
145         iteration = info[0]->ToNumber<int32_t>();
146         if (iteration < -1) {
147             iteration = DEFAULT_ITERATIONS;
148         }
149     }
150 
151     ImageAnimatorModel::GetInstance()->SetIteration(iteration);
152 }
153 
SetFillMode(const JSCallbackInfo & info)154 void JSImageAnimator::SetFillMode(const JSCallbackInfo& info)
155 {
156     if (info.Length() < 1) {
157         return;
158     }
159     int32_t fillMode = static_cast<int32_t>(DEFAULT_FILL_MODE);
160     if (info[0]->IsNumber()) {
161         fillMode = info[0]->ToNumber<int32_t>();
162         if (fillMode < static_cast<int32_t>(FillMode::NONE) || fillMode > static_cast<int32_t>(FillMode::BOTH)) {
163             fillMode = static_cast<int32_t>(DEFAULT_FILL_MODE);
164         }
165     }
166 
167     ImageAnimatorModel::GetInstance()->SetFillMode(fillMode);
168 }
169 
SetPreDecode(const JSCallbackInfo & info)170 void JSImageAnimator::SetPreDecode(const JSCallbackInfo& info)
171 {
172     if (info.Length() < 1) {
173         return;
174     }
175     int32_t preDecode = 0;
176     if (info[0]->IsNumber()) {
177         preDecode = info[0]->ToNumber<int32_t>();
178     }
179     ImageAnimatorModel::GetInstance()->SetPreDecode(preDecode);
180 }
181 
SetIsReverse(const JSCallbackInfo & info)182 void JSImageAnimator::SetIsReverse(const JSCallbackInfo& info)
183 {
184     if (info.Length() < 1) {
185         return;
186     }
187     bool isReverse = false;
188     if (info[0]->IsBoolean()) {
189         isReverse = info[0]->ToBoolean();
190     }
191     ImageAnimatorModel::GetInstance()->SetIsReverse(isReverse);
192 }
193 
SetFixedSize(const JSCallbackInfo & info)194 void JSImageAnimator::SetFixedSize(const JSCallbackInfo& info)
195 {
196     if (info.Length() < 1) {
197         return;
198     }
199     bool fixedSize = true;
200     if (info[0]->IsBoolean()) {
201         fixedSize = info[0]->ToBoolean();
202     }
203     ImageAnimatorModel::GetInstance()->SetFixedSize(fixedSize);
204 }
205 
OnStart(const JSCallbackInfo & info)206 void JSImageAnimator::OnStart(const JSCallbackInfo& info)
207 {
208     auto onStart = GetAnimatorEvent(info, "ImageAnimator.onStart");
209     ImageAnimatorModel::GetInstance()->SetOnStart(std::move(onStart));
210 }
211 
OnPause(const JSCallbackInfo & info)212 void JSImageAnimator::OnPause(const JSCallbackInfo& info)
213 {
214     auto onPause = GetAnimatorEvent(info, "ImageAnimator.onPause");
215     ImageAnimatorModel::GetInstance()->SetOnPause(std::move(onPause));
216 }
217 
OnRepeat(const JSCallbackInfo & info)218 void JSImageAnimator::OnRepeat(const JSCallbackInfo& info)
219 {
220     auto onRepeat = GetAnimatorEvent(info, "ImageAnimator.onRepeat");
221     ImageAnimatorModel::GetInstance()->SetOnRepeat(std::move(onRepeat));
222 }
223 
OnCancel(const JSCallbackInfo & info)224 void JSImageAnimator::OnCancel(const JSCallbackInfo& info)
225 {
226     auto onCancel = GetAnimatorEvent(info, "ImageAnimator.onCancel");
227     ImageAnimatorModel::GetInstance()->SetOnCancel(std::move(onCancel));
228 }
229 
OnFinish(const JSCallbackInfo & info)230 void JSImageAnimator::OnFinish(const JSCallbackInfo& info)
231 {
232     auto onFinish = GetAnimatorEvent(info, "ImageAnimator.onFinish");
233     ImageAnimatorModel::GetInstance()->SetOnFinish(std::move(onFinish));
234 }
235 
GetAnimatorEvent(const JSCallbackInfo & info,std::string && eventName)236 AnimatorEvent JSImageAnimator::GetAnimatorEvent(const JSCallbackInfo& info, std::string&& eventName)
237 {
238     if (info.Length() != 1) {
239         return {};
240     }
241     if (!info[0]->IsFunction()) {
242         return {};
243     }
244     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
245     auto animatorEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
246                              event = std::move(eventName)]() {
247         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
248         ACE_SCORING_EVENT(event);
249         func->Execute();
250     };
251     return animatorEvent;
252 }
253 
ParseImages(const JSRef<JSVal> & image,ImageProperties & imageProperties)254 void JSImageAnimator::ParseImages(const JSRef<JSVal>& image, ImageProperties& imageProperties)
255 {
256     if (!image->IsObject()) {
257         return;
258     }
259     JSRef<JSObject> jsObjImage = JSRef<JSObject>::Cast(image);
260     ParseJsMedia(jsObjImage->GetProperty("src"), imageProperties.src);
261     GetJsMediaBundleInfo(jsObjImage->GetProperty("src"), imageProperties.bundleName, imageProperties.moduleName);
262     ParseJsDimensionVp(jsObjImage->GetProperty("width"), imageProperties.width);
263     ParseJsDimensionVp(jsObjImage->GetProperty("height"), imageProperties.height);
264     ParseJsDimensionVp(jsObjImage->GetProperty("top"), imageProperties.top);
265     ParseJsDimensionVp(jsObjImage->GetProperty("left"), imageProperties.left);
266     ParseJsInt32(jsObjImage->GetProperty("duration"), imageProperties.duration);
267 }
268 
269 } // namespace OHOS::Ace::Framework
270