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