• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PAINTS_ADAPTER_ROSEN_TRANSITION_EFFECT_IMPL_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PAINTS_ADAPTER_ROSEN_TRANSITION_EFFECT_IMPL_H
18 
19 #include "modifier/rs_property.h"
20 #include "modifier/rs_property_modifier.h"
21 
22 #include "core/components_ng/render/adapter/rosen_transition_effect.h"
23 #include "core/components_ng/render/animation_utils.h"
24 
25 namespace OHOS::Ace::NG {
26 // Identity transition effect, do nothing and execute immediately.
27 class RosenIdentityTransitionEffect final : public RosenTransitionEffect {
28 public:
29     RosenIdentityTransitionEffect();
30     ~RosenIdentityTransitionEffect() override = default;
31 
32     // Identity transition effect ignores external animation option.
SetAnimationOption(const std::shared_ptr<AnimationOption> & option)33     void SetAnimationOption(const std::shared_ptr<AnimationOption>& option) override {}
34 
35 private:
36     DECLARE_ACE_TYPE(RosenIdentityTransitionEffect, RosenTransitionEffect);
37     ACE_DISALLOW_COPY_AND_MOVE(RosenIdentityTransitionEffect);
38 };
39 
40 // Template class for single property transition effect, applying identity and active value to target property/modifier.
41 template<typename Modifier, typename PropertyType>
42 class PropertyTransitionEffectTemplate : public RosenTransitionEffect {
43 public:
PropertyTransitionEffectTemplate()44     PropertyTransitionEffectTemplate() : RosenTransitionEffect() {}
PropertyTransitionEffectTemplate(PropertyType identityProperty,PropertyType activeValue)45     PropertyTransitionEffectTemplate(PropertyType identityProperty, PropertyType activeValue)
46         : RosenTransitionEffect(), identityValue_(identityProperty), activeValue_(activeValue)
47     {}
48     ~PropertyTransitionEffectTemplate() override = default;
49 
50     void SetIdentityValue(PropertyType identityValue);
51     void SetActiveValue(PropertyType activeValue);
52 
SetKeyframes(const std::vector<std::pair<float,PropertyType>> & keyframes)53     void SetKeyframes(const std::vector<std::pair<float, PropertyType>>& keyframes)
54     {
55         keyframes_ = keyframes;
56     }
57 
58 protected:
59     void OnAttach(const RefPtr<RosenRenderContext>& context, bool activeTransition) override;
60     void OnDetach(RosenRenderContext* context) override;
OnAppear()61     void OnAppear() override
62     {
63         isActive_ = false;
64         if (keyframes_.empty()) {
65             property_->Set(identityValue_);
66             return;
67         }
68         for (auto it = keyframes_.begin(); it != keyframes_.end(); ++it) {
69             AnimationUtils::AddKeyFrame(it->first, [this, &it]() { property_->Set(it->second); });
70         }
71         AnimationUtils::AddKeyFrame(1.0f, [this]() { property_->Set(identityValue_); });
72     }
OnDisappear(bool activeTransition)73     void OnDisappear(bool activeTransition) override
74     {
75         if (!activeTransition) {
76             return;
77         }
78         isActive_ = true;
79         if (keyframes_.empty()) {
80             property_->Set(activeValue_);
81             return;
82         }
83         // PLANNING: maybe we need to reverse the keyframes in disappearing animation.
84         for (auto it = keyframes_.begin(); it != keyframes_.end(); ++it) {
85             AnimationUtils::AddKeyFrame(it->first, [this, &it]() { property_->Set(it->second); });
86         }
87         AnimationUtils::AddKeyFrame(1.0f, [this]() { property_->Set(activeValue_); });
88     }
89 
90 private:
91     std::shared_ptr<Modifier> modifier_;
92     std::shared_ptr<Rosen::RSAnimatableProperty<PropertyType>> property_;
93     PropertyType identityValue_ {};
94     PropertyType activeValue_ {};
95     std::vector<std::pair<float, PropertyType>> keyframes_;
96     bool isActive_ = false;
97 
98     DECLARE_ACE_TYPE(PropertyTransitionEffectTemplate, RosenTransitionEffect);
99     ACE_DISALLOW_COPY_AND_MOVE(PropertyTransitionEffectTemplate);
100 };
101 
102 using RosenOpacityTransitionEffect = PropertyTransitionEffectTemplate<Rosen::RSAlphaModifier, float>;
103 template<>
104 RosenOpacityTransitionEffect::PropertyTransitionEffectTemplate();
105 
106 // Set pivot during transition effect.
107 class RosenPivotTransitionEffect final : public RosenTransitionEffect {
108 public:
109     RosenPivotTransitionEffect() = default;
110     RosenPivotTransitionEffect(const Dimension& centerX, const Dimension& centerY,
111         const Dimension& centerZ = Dimension(0.0));
112     ~RosenPivotTransitionEffect() override = default;
113 
114     void SetPivot(const Dimension& centerX, const Dimension& centerY, const Dimension& centerZ = Dimension(0.0,
115         DimensionUnit::VP));
116 
117 private:
118     void OnUpdateTransitionContext(
119         const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize) override;
120 
121     Dimension centerX_ { 0.5_pct };
122     Dimension centerY_ { 0.5_pct };
123     Dimension centerZ_ { 0.0_vp };
124     DECLARE_ACE_TYPE(RosenPivotTransitionEffect, RosenTransitionEffect);
125     ACE_DISALLOW_COPY_AND_MOVE(RosenPivotTransitionEffect);
126 };
127 
128 // Asymmetric transition effect, support in and out chaining with different transition effects.
129 class RosenAsymmetricTransitionEffect : public RosenTransitionEffect {
130 public:
RosenAsymmetricTransitionEffect()131     RosenAsymmetricTransitionEffect() : RosenTransitionEffect() {}
132     RosenAsymmetricTransitionEffect(
133         const RefPtr<RosenTransitionEffect>& transitionIn, const RefPtr<RosenTransitionEffect>& transitionOut);
134     ~RosenAsymmetricTransitionEffect() override = default;
135 
136     void SetTransitionInEffect(const RefPtr<RosenTransitionEffect>& transitionIn);
137     void SetTransitionOutEffect(const RefPtr<RosenTransitionEffect>& transitionOut);
GetTransitionInEffect()138     RefPtr<RosenTransitionEffect> GetTransitionInEffect()
139     {
140         return transitionIn_;
141     }
GetTransitionOutEffect()142     RefPtr<RosenTransitionEffect> GetTransitionOutEffect()
143     {
144         return transitionOut_;
145     }
146 
147 protected:
148     void OnAttach(const RefPtr<RosenRenderContext>& context, bool activeTransition) override;
149     void OnDetach(RosenRenderContext* context) override;
150     void OnAppear() override;
151     void OnDisappear(bool activeTransition) override;
152     void OnUpdateTransitionContext(
153         const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize) override;
154 
155     RefPtr<RosenTransitionEffect> transitionIn_;
156     RefPtr<RosenTransitionEffect> transitionOut_;
157 
158 private:
159     DECLARE_ACE_TYPE(RosenAsymmetricTransitionEffect, RosenTransitionEffect);
160     ACE_DISALLOW_COPY_AND_MOVE(RosenAsymmetricTransitionEffect);
161 };
162 
163 using InternalTranslateEffect = PropertyTransitionEffectTemplate<Rosen::RSTranslateModifier, Rosen::Vector2f>;
164 template<>
165 InternalTranslateEffect::PropertyTransitionEffectTemplate();
166 
167 // Move in and out to (same) screen edge.
168 class RosenMoveTransitionEffect final : public InternalTranslateEffect {
169 public:
RosenMoveTransitionEffect(TransitionEdge transitionEdge)170     explicit RosenMoveTransitionEffect(TransitionEdge transitionEdge) : edge_(transitionEdge) {}
171     ~RosenMoveTransitionEffect() override = default;
172 
173     void SetMoveEffect(TransitionEdge edge);
174 
175 private:
176     void OnUpdateTransitionContext(
177         const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize) override;
178     TransitionEdge edge_;
179     DECLARE_ACE_TYPE(RosenMoveTransitionEffect, InternalTranslateEffect);
180     ACE_DISALLOW_COPY_AND_MOVE(RosenMoveTransitionEffect);
181 };
182 
183 // Move in and out to different screen edge.
184 class RosenAsyncMoveTransitionEffect final : public RosenAsymmetricTransitionEffect {
185 public:
186     RosenAsyncMoveTransitionEffect(TransitionEdge inEdge, TransitionEdge outEdge);
187     ~RosenAsyncMoveTransitionEffect() override = default;
188 
189 private:
190     DECLARE_ACE_TYPE(RosenAsyncMoveTransitionEffect, RosenAsymmetricTransitionEffect);
191     ACE_DISALLOW_COPY_AND_MOVE(RosenAsyncMoveTransitionEffect);
192 };
193 
194 // Move in and out to different direction, by node size.
195 class RosenSlideTransitionEffect final : public RosenAsymmetricTransitionEffect {
196 public:
197     RosenSlideTransitionEffect();
198     RosenSlideTransitionEffect(TransitionEdge inEdge, TransitionEdge outEdge);
199     ~RosenSlideTransitionEffect() override = default;
200 
201 private:
202     void OnUpdateTransitionContext(
203         const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize) override;
204     static Rosen::Vector2f GetTranslateValue(TransitionEdge edge, const RectF& rect);
205     TransitionEdge inEdge_;
206     TransitionEdge outEdge_;
207     DECLARE_ACE_TYPE(RosenSlideTransitionEffect, RosenAsymmetricTransitionEffect);
208     ACE_DISALLOW_COPY_AND_MOVE(RosenSlideTransitionEffect);
209 };
210 
211 // Helper class for compositing transition effects.
212 template<typename... effects>
213 class RosenCompositeTransitionEffect : public RosenTransitionEffect {
214 public:
215     RosenCompositeTransitionEffect() = default;
216     ~RosenCompositeTransitionEffect() override = default;
217 
218 protected:
219     std::tuple<effects...> effects_;
220 
OnAttach(const RefPtr<RosenRenderContext> & context,bool activeTransition)221     void OnAttach(const RefPtr<RosenRenderContext>& context, bool activeTransition) override
222     {
223         std::apply([&](auto&&... effect) { (effect.Attach(context, activeTransition), ...); }, effects_);
224     }
OnDetach(RosenRenderContext * context)225     void OnDetach(RosenRenderContext* context) override
226     {
227         std::apply([&](auto&&... effect) { (effect.Detach(context), ...); }, effects_);
228     }
OnAppear()229     void OnAppear() override
230     {
231         std::apply([&](auto&&... effect) { (effect.Appear(), ...); }, effects_);
232     }
OnDisappear(bool activeTransition)233     void OnDisappear(bool activeTransition) override
234     {
235         std::apply([&](auto&&... effect) { (effect.Disappear(activeTransition), ...); }, effects_);
236     }
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)237     void OnUpdateTransitionContext(
238         const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize) override
239     {
240         std::apply(
241             [&](auto&&... effect) { (effect.UpdateTransitionContext(context, selfRect, viewSize), ...); }, effects_);
242     }
243 
244 private:
245     DECLARE_ACE_TYPE(RosenCompositeTransitionEffect, RosenTransitionEffect);
246     ACE_DISALLOW_COPY_AND_MOVE(RosenCompositeTransitionEffect);
247 };
248 
249 using InternalTranslateZEffect = PropertyTransitionEffectTemplate<Rosen::RSTranslateZModifier, float>;
250 template<>
251 InternalTranslateZEffect::PropertyTransitionEffectTemplate();
252 // 3D Translate effect that accepts Dimension.
253 class RosenTranslateTransitionEffect final
254     : public RosenCompositeTransitionEffect<InternalTranslateEffect, InternalTranslateZEffect> {
255 public:
RosenTranslateTransitionEffect(const TranslateOptions & option)256     explicit RosenTranslateTransitionEffect(const TranslateOptions& option) : translateValue_(option) {}
257     ~RosenTranslateTransitionEffect() override = default;
258 
259     void SetTranslateEffect(const TranslateOptions& option);
260 
261 private:
262     void OnUpdateTransitionContext(
263         const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize) override;
264     TranslateOptions translateValue_;
265     DECLARE_ACE_TYPE(RosenTranslateTransitionEffect, RosenCompositeTransitionEffect);
266     ACE_DISALLOW_COPY_AND_MOVE(RosenTranslateTransitionEffect);
267 };
268 
269 // 3D rotation composite effect with pivot.
270 using InternalRotationXEffect = PropertyTransitionEffectTemplate<Rosen::RSRotationXModifier, float>;
271 using InternalRotationYEffect = PropertyTransitionEffectTemplate<Rosen::RSRotationYModifier, float>;
272 using InternalRotationZEffect = PropertyTransitionEffectTemplate<Rosen::RSRotationModifier, float>;
273 using InternalCameraDistanceEffect = PropertyTransitionEffectTemplate<Rosen::RSCameraDistanceModifier, float>;
274 template<>
275 InternalRotationXEffect::PropertyTransitionEffectTemplate();
276 template<>
277 InternalRotationYEffect::PropertyTransitionEffectTemplate();
278 template<>
279 InternalRotationZEffect::PropertyTransitionEffectTemplate();
280 template<>
281 InternalCameraDistanceEffect::PropertyTransitionEffectTemplate();
282 class RosenRotation3DTransitionEffect final
283     : public RosenCompositeTransitionEffect<InternalRotationXEffect, InternalRotationYEffect, InternalRotationZEffect,
284           RosenPivotTransitionEffect, InternalCameraDistanceEffect> {
285 public:
286     explicit RosenRotation3DTransitionEffect(const RotateOptions& options);
287     ~RosenRotation3DTransitionEffect() override = default;
288 
289     void SetRotateEffect(const RotateOptions& options);
290 
291 private:
292     DECLARE_ACE_TYPE(RosenRotation3DTransitionEffect, RosenCompositeTransitionEffect);
293     ACE_DISALLOW_COPY_AND_MOVE(RosenRotation3DTransitionEffect);
294 };
295 
296 using InternalScaleEffect = PropertyTransitionEffectTemplate<Rosen::RSScaleModifier, Rosen::Vector2f>;
297 template<>
298 InternalScaleEffect::PropertyTransitionEffectTemplate();
299 // 2D scale composite effect with pivot.
300 class RosenScaleTransitionEffect final
301     : public RosenCompositeTransitionEffect<InternalScaleEffect, RosenPivotTransitionEffect> {
302 public:
303     explicit RosenScaleTransitionEffect(const ScaleOptions& options);
304     ~RosenScaleTransitionEffect() override = default;
305 
306     void SetScaleEffect(const ScaleOptions& options);
307 
308 private:
309     DECLARE_ACE_TYPE(RosenScaleTransitionEffect, RosenCompositeTransitionEffect);
310     ACE_DISALLOW_COPY_AND_MOVE(RosenScaleTransitionEffect);
311 };
312 
313 class RosenSlideSwitchTransitionEffect final
314     : public RosenCompositeTransitionEffect<RosenSlideTransitionEffect, InternalScaleEffect> {
315 public:
316     RosenSlideSwitchTransitionEffect();
317     ~RosenSlideSwitchTransitionEffect() override = default;
318     void SetAnimationOption(const std::shared_ptr<AnimationOption>& option) override;
319 
320 private:
321     DECLARE_ACE_TYPE(RosenSlideSwitchTransitionEffect, RosenCompositeTransitionEffect);
322     ACE_DISALLOW_COPY_AND_MOVE(RosenSlideSwitchTransitionEffect);
323 };
324 } // namespace OHOS::Ace::NG
325 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PAINTS_ADAPTER_ROSEN_TRANSITION_EFFECT_IMPL_H
326