• 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     if (info.Length() > 0 && info[0]->IsNumber()) {
81         auto effect = info[0]->ToNumber<int32_t>();
82 
83         if (effect >= static_cast<int32_t>(SlideEffect::LEFT) && effect <= static_cast<int32_t>(SlideEffect::BOTTOM)) {
84             PageTransitionModel::GetInstance()->SetSlideEffect(static_cast<SlideEffect>(effect));
85         }
86     }
87 }
88 
Translate(const JSCallbackInfo & info)89 void JSPageTransition::Translate(const JSCallbackInfo& info)
90 {
91     if (info.Length() > 0 && info[0]->IsObject()) {
92         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
93         NG::TranslateOptions option;
94         CalcDimension length;
95         if (JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("x"), length)) {
96             option.x = length;
97         }
98         if (JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("y"), length)) {
99             option.y = length;
100         }
101         if (JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("z"), length)) {
102             option.z = length;
103         }
104         PageTransitionModel::GetInstance()->SetTranslateEffect(option);
105     }
106 }
107 
Scale(const JSCallbackInfo & info)108 void JSPageTransition::Scale(const JSCallbackInfo& info)
109 {
110     if (info.Length() > 0 && info[0]->IsObject()) {
111         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
112         // default: x, y, z (1.0, 1.0, 1.0)
113         double scaleX = 1.0;
114         double scaleY = 1.0;
115         double scaleZ = 1.0;
116         JSViewAbstract::ParseJsDouble(jsObj->GetProperty("x"), scaleX);
117         JSViewAbstract::ParseJsDouble(jsObj->GetProperty("y"), scaleY);
118         JSViewAbstract::ParseJsDouble(jsObj->GetProperty("z"), scaleZ);
119         // default centerX, centerY 50% 50%;
120         CalcDimension centerX = 0.5_pct;
121         CalcDimension centerY = 0.5_pct;
122 
123         // if specify centerX
124         CalcDimension length;
125         if (JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerX"), length)) {
126             centerX = length;
127         }
128         // if specify centerY
129         if (JSViewAbstract::ParseJsDimensionVp(jsObj->GetProperty("centerY"), length)) {
130             centerY = length;
131         }
132         NG::ScaleOptions option(
133             static_cast<float>(scaleX), static_cast<float>(scaleY), static_cast<float>(scaleZ), centerX, centerY);
134         PageTransitionModel::GetInstance()->SetScaleEffect(option);
135     }
136 }
137 
Opacity(const JSCallbackInfo & info)138 void JSPageTransition::Opacity(const JSCallbackInfo& info)
139 {
140     if (info.Length() < 1) {
141         return;
142     }
143     double opacity = 0.0;
144     if (!JSViewAbstract::ParseJsDouble(info[0], opacity)) {
145         return;
146     }
147     if (LessNotEqual(opacity, 0.0)) {
148         opacity = 1.0;
149     }
150     PageTransitionModel::GetInstance()->SetOpacityEffect(static_cast<float>(opacity));
151 }
152 
JsHandlerOnEnter(const JSCallbackInfo & info)153 void JSPageTransition::JsHandlerOnEnter(const JSCallbackInfo& info)
154 {
155     if (info.Length() < 1 || !info[0]->IsFunction()) {
156         return;
157     }
158 
159     RefPtr<JsPageTransitionFunction> function =
160         AceType::MakeRefPtr<JsPageTransitionFunction>(JSRef<JSFunc>::Cast(info[0]));
161 
162     auto onEnterHandler = [execCtx = info.GetExecutionContext(), func = std::move(function)](
163                               RouteType type, const float& progress) {
164         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
165         ACE_SCORING_EVENT("PageTransition.onEnter");
166         func->Execute(type, progress);
167     };
168 
169     PageTransitionModel::GetInstance()->SetOnEnter(std::move(onEnterHandler));
170 }
171 
JsHandlerOnExit(const JSCallbackInfo & info)172 void JSPageTransition::JsHandlerOnExit(const JSCallbackInfo& info)
173 {
174     if (info.Length() < 1 || !info[0]->IsFunction()) {
175         return;
176     }
177 
178     RefPtr<JsPageTransitionFunction> function =
179         AceType::MakeRefPtr<JsPageTransitionFunction>(JSRef<JSFunc>::Cast(info[0]));
180 
181     auto onExitHandler = [execCtx = info.GetExecutionContext(), func = std::move(function)](
182                              RouteType type, const float& progress) {
183         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
184         ACE_SCORING_EVENT("PageTransition.onExit");
185         func->Execute(type, progress);
186     };
187 
188     PageTransitionModel::GetInstance()->SetOnExit(std::move(onExitHandler));
189 }
190 
Create(const JSCallbackInfo & info)191 void JSPageTransition::Create(const JSCallbackInfo& info)
192 {
193     PageTransitionModel::GetInstance()->Create();
194 }
195 
Pop()196 void JSPageTransition::Pop()
197 {
198     PageTransitionModel::GetInstance()->Pop();
199 }
200 
ParseTransitionOption(const JSRef<JSVal> & transitionArgs)201 PageTransitionOption JSPageTransition::ParseTransitionOption(const JSRef<JSVal>& transitionArgs)
202 {
203     PageTransitionOption option;
204     const int32_t defaultDuration = 1000;
205     option.duration = defaultDuration;
206     option.curve = Curves::LINEAR;
207     if (!transitionArgs->IsObject()) {
208         return option;
209     }
210 
211     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(transitionArgs);
212     option.duration = jsObj->GetPropertyValue<int32_t>("duration", defaultDuration);
213     if (option.duration < 0) {
214         option.duration = defaultDuration;
215     }
216     option.delay = jsObj->GetPropertyValue<int32_t>("delay", 0);
217     auto routeTypeTmp = jsObj->GetPropertyValue<int32_t>("type", static_cast<int32_t>(RouteType::NONE));
218     if (routeTypeTmp >= static_cast<int32_t>(RouteType::NONE) &&
219         routeTypeTmp <= static_cast<int32_t>(RouteType::POP)) {
220         option.routeType = static_cast<RouteType>(routeTypeTmp);
221     }
222     JSRef<JSVal> curveArgs = jsObj->GetProperty("curve");
223     RefPtr<Curve> curve;
224     if (curveArgs->IsString()) {
225         curve = CreateCurve(curveArgs->ToString(), false);
226     } else if (curveArgs->IsObject()) {
227         JSRef<JSVal> curveString = JSRef<JSObject>::Cast(curveArgs)->GetProperty("__curveString");
228         if (curveString->IsString()) {
229             curve = CreateCurve(curveString->ToString(), false);
230         }
231     }
232     if (curve) {
233         option.curve = curve;
234     }
235     return option;
236 }
237 
Create(const JSCallbackInfo & info)238 void JSPageTransitionEnter::Create(const JSCallbackInfo& info)
239 {
240     if (info.Length() > 0 && info[0]->IsObject()) {
241         auto option = ParseTransitionOption(info[0]);
242         PageTransitionModel::GetInstance()->CreateTransition(PageTransitionType::ENTER, option);
243     }
244 }
245 
Create(const JSCallbackInfo & info)246 void JSPageTransitionExit::Create(const JSCallbackInfo& info)
247 {
248     if (info.Length() > 0 && info[0]->IsObject()) {
249         auto option = ParseTransitionOption(info[0]);
250         PageTransitionModel::GetInstance()->CreateTransition(PageTransitionType::EXIT, option);
251     }
252 }
253 
254 } // namespace OHOS::Ace::Framework
255