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