• 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 "frameworks/bridge/declarative_frontend/jsview/js_page_transition.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/engine/functions/js_page_transition_function.h"
20 #include "bridge/declarative_frontend/jsview/models/page_transition_model_impl.h"
21 #include "core/components_ng/pattern/stage/page_transition_model_ng.h"
22 
23 namespace OHOS::Ace {
24 std::unique_ptr<PageTransitionModel> PageTransitionModel::instance_ = nullptr;
25 std::mutex PageTransitionModel::mutex_;
26 
GetInstance()27 PageTransitionModel* PageTransitionModel::GetInstance()
28 {
29     if (!instance_) {
30         std::lock_guard<std::mutex> lock(mutex_);
31         if (!instance_) {
32 #ifdef NG_BUILD
33             instance_.reset(new NG::PageTransitionModelNG());
34 #else
35             if (Container::IsCurrentUseNewPipeline()) {
36                 instance_.reset(new NG::PageTransitionModelNG());
37             } else {
38                 instance_.reset(new Framework::PageTransitionModelImpl());
39             }
40 #endif
41         }
42     }
43     return instance_.get();
44 }
45 } // namespace OHOS::Ace
46 
47 namespace OHOS::Ace::Framework {
48 
JSBind(BindingTarget globalObj)49 void JSPageTransition::JSBind(BindingTarget globalObj)
50 {
51     JSClass<JSPageTransition>::Declare("PageTransition");
52     MethodOptions opt = MethodOptions::NONE;
53     JSClass<JSPageTransition>::StaticMethod("create", &JSPageTransition::Create, opt);
54     JSClass<JSPageTransition>::StaticMethod("pop", &JSPageTransition::Pop);
55     JSClass<JSPageTransition>::Bind<>(globalObj);
56 
57     JSClass<JSPageTransitionEnter>::Declare("PageTransitionEnter");
58     JSClass<JSPageTransitionEnter>::StaticMethod("create", &JSPageTransitionEnter::Create, opt);
59     JSClass<JSPageTransitionEnter>::StaticMethod("slide", &JSPageTransition::Slide);
60     JSClass<JSPageTransitionEnter>::StaticMethod("translate", &JSPageTransition::Translate);
61     JSClass<JSPageTransitionEnter>::StaticMethod("scale", &JSPageTransition::Scale);
62     JSClass<JSPageTransitionEnter>::StaticMethod("opacity", &JSPageTransition::Opacity);
63     JSClass<JSPageTransitionEnter>::StaticMethod("onEnter", &JSPageTransition::JsHandlerOnEnter);
64     JSClass<JSPageTransitionEnter>::StaticMethod("pop", &JSPageTransitionEnter::Pop);
65     JSClass<JSPageTransitionEnter>::Bind<>(globalObj);
66 
67     JSClass<JSPageTransitionExit>::Declare("PageTransitionExit");
68     JSClass<JSPageTransitionExit>::StaticMethod("create", &JSPageTransitionExit::Create, opt);
69     JSClass<JSPageTransitionExit>::StaticMethod("slide", &JSPageTransition::Slide);
70     JSClass<JSPageTransitionExit>::StaticMethod("translate", &JSPageTransition::Translate);
71     JSClass<JSPageTransitionExit>::StaticMethod("scale", &JSPageTransition::Scale);
72     JSClass<JSPageTransitionExit>::StaticMethod("opacity", &JSPageTransition::Opacity);
73     JSClass<JSPageTransitionExit>::StaticMethod("onExit", &JSPageTransition::JsHandlerOnExit);
74     JSClass<JSPageTransitionExit>::StaticMethod("pop", &JSPageTransitionExit::Pop);
75     JSClass<JSPageTransitionExit>::Bind<>(globalObj);
76 }
77 
Slide(const JSCallbackInfo & info)78 void JSPageTransition::Slide(const JSCallbackInfo& info)
79 {
80     LOGD("JSPageTransition::Slide");
81     if (info.Length() > 0 && info[0]->IsNumber()) {
82         auto effect = info[0]->ToNumber<int32_t>();
83 
84         if (effect >= static_cast<int32_t>(SlideEffect::LEFT) && effect <= static_cast<int32_t>(SlideEffect::BOTTOM)) {
85             PageTransitionModel::GetInstance()->SetSlideEffect(static_cast<SlideEffect>(effect));
86         }
87     }
88 }
89 
Translate(const JSCallbackInfo & info)90 void JSPageTransition::Translate(const JSCallbackInfo& info)
91 {
92     LOGD("JSPageTransitionTranslate");
93     if (info.Length() > 0 && info[0]->IsObject()) {
94         auto args = JsonUtil::ParseJsonString(info[0]->ToString());
95         if (!args || args->IsNull()) {
96             LOGE("JSTransition Translate failed json value is nullptr or json object is null");
97             return;
98         }
99 
100         NG::TranslateOptions option;
101 
102         CalcDimension length;
103         if (JSViewAbstract::ParseJsonDimensionVp(args->GetValue("x"), length)) {
104             option.x = length;
105         }
106         if (JSViewAbstract::ParseJsonDimensionVp(args->GetValue("y"), length)) {
107             option.y = length;
108         }
109         if (JSViewAbstract::ParseJsonDimensionVp(args->GetValue("z"), length)) {
110             option.z = length;
111         }
112         PageTransitionModel::GetInstance()->SetTranslateEffect(option);
113     }
114 }
115 
Scale(const JSCallbackInfo & info)116 void JSPageTransition::Scale(const JSCallbackInfo& info)
117 {
118     LOGD("JSPageTransition::Scale");
119     if (info.Length() > 0 && info[0]->IsObject()) {
120         auto args = JsonUtil::ParseJsonString(info[0]->ToString());
121         if (!args || args->IsNull()) {
122             LOGE("JSTransition Scale failed, json value is nullptr or json object is null");
123             return;
124         }
125 
126         // default: x, y, z (1.0, 1.0, 1.0)
127         double scaleX = 1.0;
128         double scaleY = 1.0;
129         double scaleZ = 1.0;
130         JSViewAbstract::ParseJsonDouble(args->GetValue("x"), scaleX);
131         JSViewAbstract::ParseJsonDouble(args->GetValue("y"), scaleY);
132         JSViewAbstract::ParseJsonDouble(args->GetValue("z"), scaleZ);
133         // default centerX, centerY 50% 50%;
134         CalcDimension centerX = 0.5_pct;
135         CalcDimension centerY = 0.5_pct;
136 
137         // if specify centerX
138         CalcDimension length;
139         if (JSViewAbstract::ParseJsonDimensionVp(args->GetValue("centerX"), length)) {
140             centerX = length;
141         }
142         // if specify centerY
143         if (JSViewAbstract::ParseJsonDimensionVp(args->GetValue("centerY"), length)) {
144             centerY = length;
145         }
146         NG::ScaleOptions option(
147             static_cast<float>(scaleX), static_cast<float>(scaleY), static_cast<float>(scaleZ), centerX, centerY);
148         PageTransitionModel::GetInstance()->SetScaleEffect(option);
149     }
150 }
151 
Opacity(const JSCallbackInfo & info)152 void JSPageTransition::Opacity(const JSCallbackInfo& info)
153 {
154     LOGD("JSPageTransition::Opacity");
155     if (info.Length() < 1) {
156         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
157         return;
158     }
159     double opacity = 0.0;
160     if (!JSViewAbstract::ParseJsDouble(info[0], opacity)) {
161         return;
162     }
163     PageTransitionModel::GetInstance()->SetOpacityEffect(static_cast<float>(opacity));
164 }
165 
JsHandlerOnEnter(const JSCallbackInfo & info)166 void JSPageTransition::JsHandlerOnEnter(const JSCallbackInfo& info)
167 {
168     LOGD("JSPageTransition::JsHandlerOnEnter");
169     if (info.Length() < 1 || !info[0]->IsFunction()) {
170         LOGE("JsHandlerOnEnter info.Length < 0 or info[0] is not function");
171         return;
172     }
173 
174     RefPtr<JsPageTransitionFunction> function =
175         AceType::MakeRefPtr<JsPageTransitionFunction>(JSRef<JSFunc>::Cast(info[0]));
176 
177     auto onEnterHandler = [execCtx = info.GetExecutionContext(), func = std::move(function)](
178                               RouteType type, const float& progress) {
179         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
180         ACE_SCORING_EVENT("PageTransition.onEnter");
181         func->Execute(type, progress);
182     };
183 
184     PageTransitionModel::GetInstance()->SetOnEnter(std::move(onEnterHandler));
185 }
186 
JsHandlerOnExit(const JSCallbackInfo & info)187 void JSPageTransition::JsHandlerOnExit(const JSCallbackInfo& info)
188 {
189     LOGD("JSPageTransition::JsHandlerOnExit");
190     if (info.Length() < 1 || !info[0]->IsFunction()) {
191         LOGE("JsHandlerOnExit info.Length < 0 or info[0] is not function");
192         return;
193     }
194 
195     RefPtr<JsPageTransitionFunction> function =
196         AceType::MakeRefPtr<JsPageTransitionFunction>(JSRef<JSFunc>::Cast(info[0]));
197 
198     auto onExitHandler = [execCtx = info.GetExecutionContext(), func = std::move(function)](
199                              RouteType type, const float& progress) {
200         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
201         ACE_SCORING_EVENT("PageTransition.onExit");
202         func->Execute(type, progress);
203     };
204 
205     PageTransitionModel::GetInstance()->SetOnExit(std::move(onExitHandler));
206 }
207 
Create(const JSCallbackInfo & info)208 void JSPageTransition::Create(const JSCallbackInfo& info)
209 {
210     LOGD("JSPageTransition::JSTransition::Create");
211     PageTransitionModel::GetInstance()->Create();
212 }
213 
Pop()214 void JSPageTransition::Pop()
215 {
216     LOGD("JSPageTransition::Pop");
217     PageTransitionModel::GetInstance()->Pop();
218 }
219 
ParseTransitionOption(const std::unique_ptr<JsonValue> & transitionArgs)220 PageTransitionOption JSPageTransition::ParseTransitionOption(const std::unique_ptr<JsonValue>& transitionArgs)
221 {
222     PageTransitionOption option;
223     const int32_t defaultDuration = 1000;
224     option.duration = defaultDuration;
225     option.curve = Curves::LINEAR;
226     if (transitionArgs && !transitionArgs->IsNull()) {
227         option.duration = transitionArgs->GetInt("duration", defaultDuration);
228         if (option.duration < 0) {
229             option.duration = defaultDuration;
230         }
231         option.delay = transitionArgs->GetInt("delay", 0);
232         auto routeTypeTmp = transitionArgs->GetInt("type", static_cast<int32_t>(RouteType::NONE));
233         if (routeTypeTmp >= static_cast<int32_t>(RouteType::NONE) &&
234             routeTypeTmp <= static_cast<int32_t>(RouteType::POP)) {
235             option.routeType = static_cast<RouteType>(routeTypeTmp);
236         } else {
237             LOGW("CreateTransition RouteType out of range");
238         }
239 
240         auto curveArgs = transitionArgs->GetValue("curve");
241         RefPtr<Curve> curve;
242         if (curveArgs->IsString()) {
243             curve = CreateCurve(curveArgs->GetString(), false);
244         } else if (curveArgs->IsObject()) {
245             auto curveString = curveArgs->GetValue("__curveString");
246             if (curveString) {
247                 curve = CreateCurve(curveString->GetString(), false);
248             }
249         }
250         if (curve) {
251             option.curve = curve;
252         }
253     }
254     return option;
255 }
256 
Create(const JSCallbackInfo & info)257 void JSPageTransitionEnter::Create(const JSCallbackInfo& info)
258 {
259     LOGD("JSPageTransitionEnter::Create");
260     if (info.Length() > 0 && info[0]->IsObject()) {
261         auto transitionArgs = JsonUtil::ParseJsonString(info[0]->ToString());
262         auto option = ParseTransitionOption(transitionArgs);
263         PageTransitionModel::GetInstance()->CreateTransition(PageTransitionType::ENTER, option);
264     }
265 }
266 
Create(const JSCallbackInfo & info)267 void JSPageTransitionExit::Create(const JSCallbackInfo& info)
268 {
269     LOGD("JSPageTransitionExit::Create");
270     if (info.Length() > 0 && info[0]->IsObject()) {
271         auto transitionArgs = JsonUtil::ParseJsonString(info[0]->ToString());
272         auto option = ParseTransitionOption(transitionArgs);
273         PageTransitionModel::GetInstance()->CreateTransition(PageTransitionType::EXIT, option);
274     }
275 }
276 
277 } // namespace OHOS::Ace::Framework
278