• 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         LOGE("JSImageAnimator: The arg is wrong, it is supposed to have one object argument.");
87         return;
88     }
89     if (info[0]->IsNull()) {
90         LOGE("JSImageAnimator: info is null.");
91         return;
92     }
93     if (!info[0]->IsArray()) {
94         LOGE("JSImageAnimator: info is not array.");
95         return;
96     }
97     JSRef<JSArray> imageArray = JSRef<JSArray>::Cast(info[0]);
98     std::vector<ImageProperties> images;
99     for (uint32_t i = 0; i < imageArray->Length(); ++i) {
100         ImageProperties imageProperties;
101         ParseImages(imageArray->GetValueAt(i), imageProperties);
102         images.push_back(imageProperties);
103     }
104 
105     ImageAnimatorModel::GetInstance()->SetImages(images);
106 }
107 
SetState(int32_t state)108 void JSImageAnimator::SetState(int32_t state)
109 {
110     if (state < static_cast<int32_t>(Animator::Status::IDLE) ||
111         state > static_cast<int32_t>(Animator::Status::STOPPED)) {
112         LOGW("ImageAnimator SetState %{public}d, invalid, use default AnimationStatus.Initial", state);
113         state = static_cast<int32_t>(Animator::Status::IDLE);
114     }
115 
116     ImageAnimatorModel::GetInstance()->SetState(state);
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 
126     ImageAnimatorModel::GetInstance()->SetDuration(duration);
127 }
128 
SetIteration(int32_t iteration)129 void JSImageAnimator::SetIteration(int32_t iteration)
130 {
131     if (iteration < -1) {
132         LOGW("ImageAnimator SetIteration %{public}d, invalid, use default %{public}d", iteration, DEFAULT_ITERATIONS);
133         iteration = DEFAULT_ITERATIONS;
134     }
135 
136     ImageAnimatorModel::GetInstance()->SetIteration(iteration);
137 }
138 
SetFillMode(int32_t fillMode)139 void JSImageAnimator::SetFillMode(int32_t fillMode)
140 {
141     if (fillMode < static_cast<int32_t>(FillMode::NONE) || fillMode > static_cast<int32_t>(FillMode::BOTH)) {
142         LOGW("ImageAnimator SetFillMode %{public}d, invalid, use default %{public}d", fillMode,
143             static_cast<int32_t>(DEFAULT_FILL_MODE));
144         fillMode = static_cast<int32_t>(DEFAULT_FILL_MODE);
145     }
146 
147     ImageAnimatorModel::GetInstance()->SetFillMode(fillMode);
148 }
149 
SetPreDecode(int32_t preDecode)150 void JSImageAnimator::SetPreDecode(int32_t preDecode)
151 {
152     ImageAnimatorModel::GetInstance()->SetPreDecode(preDecode);
153 }
154 
SetIsReverse(bool isReverse)155 void JSImageAnimator::SetIsReverse(bool isReverse)
156 {
157     ImageAnimatorModel::GetInstance()->SetIsReverse(isReverse);
158 }
159 
SetFixedSize(bool fixedSize)160 void JSImageAnimator::SetFixedSize(bool fixedSize)
161 {
162     ImageAnimatorModel::GetInstance()->SetFixedSize(fixedSize);
163 }
164 
OnStart(const JSCallbackInfo & info)165 void JSImageAnimator::OnStart(const JSCallbackInfo& info)
166 {
167     auto onStart = GetAnimatorEvent(info, "ImageAnimator.onStart");
168     ImageAnimatorModel::GetInstance()->SetOnStart(std::move(onStart));
169 }
170 
OnPause(const JSCallbackInfo & info)171 void JSImageAnimator::OnPause(const JSCallbackInfo& info)
172 {
173     auto onPause = GetAnimatorEvent(info, "ImageAnimator.onPause");
174     ImageAnimatorModel::GetInstance()->SetOnPause(std::move(onPause));
175 }
176 
OnRepeat(const JSCallbackInfo & info)177 void JSImageAnimator::OnRepeat(const JSCallbackInfo& info)
178 {
179     auto onRepeat = GetAnimatorEvent(info, "ImageAnimator.onRepeat");
180     ImageAnimatorModel::GetInstance()->SetOnRepeat(std::move(onRepeat));
181 }
182 
OnCancel(const JSCallbackInfo & info)183 void JSImageAnimator::OnCancel(const JSCallbackInfo& info)
184 {
185     auto onCancel = GetAnimatorEvent(info, "ImageAnimator.onCancel");
186     ImageAnimatorModel::GetInstance()->SetOnCancel(std::move(onCancel));
187 }
188 
OnFinish(const JSCallbackInfo & info)189 void JSImageAnimator::OnFinish(const JSCallbackInfo& info)
190 {
191     auto onFinish = GetAnimatorEvent(info, "ImageAnimator.onFinish");
192     ImageAnimatorModel::GetInstance()->SetOnFinish(std::move(onFinish));
193 }
194 
GetAnimatorEvent(const JSCallbackInfo & info,std::string && eventName)195 AnimatorEvent JSImageAnimator::GetAnimatorEvent(const JSCallbackInfo& info, std::string&& eventName)
196 {
197     if (info.Length() != 1) {
198         LOGW("JSImageAnimator: The arg is wrong, it is supposed to have one function argument. event:%{public}s",
199             eventName.c_str());
200         return {};
201     }
202     if (!info[0]->IsFunction()) {
203         LOGE("JSImageAnimator: info[0] is not a function. event:%{public}s", eventName.c_str());
204         return {};
205     }
206     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[0]));
207     auto animatorEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc),
208                              event = std::move(eventName)]() {
209         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
210         ACE_SCORING_EVENT(event);
211         func->Execute();
212     };
213     return animatorEvent;
214 }
215 
ParseImages(const JSRef<JSVal> & image,ImageProperties & imageProperties)216 void JSImageAnimator::ParseImages(const JSRef<JSVal>& image, ImageProperties& imageProperties)
217 {
218     if (!image->IsObject()) {
219         LOGE("image is not Object.");
220         return;
221     }
222     JSRef<JSObject> jsObjImage = JSRef<JSObject>::Cast(image);
223     if (!ParseJsMedia(jsObjImage->GetProperty("src"), imageProperties.src)) {
224         LOGE("parse image property src failed!");
225     }
226     ParseJsDimensionVp(jsObjImage->GetProperty("width"), imageProperties.width);
227     ParseJsDimensionVp(jsObjImage->GetProperty("height"), imageProperties.height);
228     ParseJsDimensionVp(jsObjImage->GetProperty("top"), imageProperties.top);
229     ParseJsDimensionVp(jsObjImage->GetProperty("left"), imageProperties.left);
230     ParseJsInt32(jsObjImage->GetProperty("duration"), imageProperties.duration);
231 }
232 
233 } // namespace OHOS::Ace::Framework
234