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