1 /* 2 * Copyright (c) 2021 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_TRANSFORM_RENDER_TRANSFORM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TRANSFORM_RENDER_TRANSFORM_H 18 19 #include "base/geometry/animatable_matrix4.h" 20 #include "base/geometry/axis.h" 21 #include "base/geometry/matrix4.h" 22 #include "base/geometry/transform_util.h" 23 #include "core/animation/animatable_transform_operation.h" 24 #include "core/animation/animator.h" 25 #include "core/animation/keyframe_animation.h" 26 #include "core/components/common/properties/motion_path_evaluator.h" 27 #include "core/components/common/properties/tween_option.h" 28 #include "core/components/transform/click_spring_effect.h" 29 #include "core/gestures/raw_recognizer.h" 30 #include "core/pipeline/base/render_node.h" 31 32 namespace OHOS::Ace { 33 34 enum class TransformType { 35 PERSPECTIVE, 36 }; 37 38 class RenderTransform : public RenderNode { 39 DECLARE_ACE_TYPE(RenderTransform, RenderNode); 40 41 public: 42 static Matrix4 GetTransformByOffset(Matrix4 matrix, const Offset& offset); 43 static RefPtr<RenderNode> Create(); 44 void Translate(const Dimension& x, const Dimension& y, const Dimension& z); 45 void Translate(const Dimension& x, const Dimension& y); 46 void Scale(float value); 47 void Scale(float x, float y); 48 void Scale(float x, float y, float z); 49 void Skew(float x, float y); 50 void Rotate(float angle, float x, float y, float z); 51 void RotateX(float angle); 52 void RotateY(float angle); 53 void RotateZ(float angle); 54 void Matrix3D(Matrix4 m); 55 void Perspective(const Dimension& distance); 56 void ResetTransform(); 57 void UpdateTransform(); 58 void SetTouchable(bool enable); 59 void Update(const RefPtr<Component>& component) override; 60 void PerformLayout() override; 61 void UpdateTransformOrigin(); Mirror(const Offset & center,const Offset & global)62 virtual void Mirror(const Offset& center, const Offset& global) {} 63 SetMaxScaleXY(double maxScaleXY)64 void SetMaxScaleXY(double maxScaleXY) 65 { 66 maxScaleXY_ = maxScaleXY; 67 } 68 MarkNeedUpdateOrigin()69 void MarkNeedUpdateOrigin() 70 { 71 needUpdateOrigin_ = true; 72 } 73 SetTransformOrigin(const Dimension & x,const Dimension & y)74 void SetTransformOrigin(const Dimension& x, const Dimension& y) 75 { 76 originX_ = x; 77 originY_ = y; 78 MarkNeedRender(); 79 } GetTransformOrigin()80 DimensionOffset GetTransformOrigin() const 81 { 82 return DimensionOffset(originX_, originY_); 83 } GetOriginX()84 const Dimension& GetOriginX() const 85 { 86 return originX_; 87 } GetOriginY()88 const Dimension& GetOriginY() const 89 { 90 return originY_; 91 } 92 SetDisableClickEffect(bool isDisable)93 void SetDisableClickEffect(bool isDisable) 94 { 95 disableClickEffect_ = isDisable; 96 } 97 GetTransformEffects()98 const AnimatableTransformOperations& GetTransformEffects() const 99 { 100 return transformEffects_; 101 } 102 UpdateTransformLayer()103 virtual void UpdateTransformLayer() {} 104 105 Offset GetGlobalOffsetExternal() const override; 106 107 void OnTransition(TransitionType type, int32_t id) override; 108 109 bool HasDisappearingTransition(int32_t nodeId) override; 110 OnAttachContext()111 void OnAttachContext() override 112 { 113 transformAnimation_.SetContextAndCallback(context_, [weak = AceType::WeakClaim(this)]() { 114 auto renderNode = weak.Upgrade(); 115 if (renderNode) { 116 renderNode->MarkNeedLayout(); 117 renderNode->MarkNeedRender(); 118 } 119 }); 120 121 transformEffects_.SetContextAndCallback(context_, [weak = AceType::WeakClaim(this)]() { 122 auto renderNode = weak.Upgrade(); 123 if (renderNode) { 124 renderNode->needUpdateTransform_ = true; 125 renderNode->ResetTransform(); 126 renderNode->MarkNeedRender(); 127 } 128 }); 129 } 130 SetMotionPathEvaluator(const RefPtr<MotionPathEvaluator> & evaluator)131 void SetMotionPathEvaluator(const RefPtr<MotionPathEvaluator>& evaluator) 132 { 133 auto context = context_.Upgrade(); 134 if (!context) { 135 LOGE("SetMotionPathEvaluator failed, context is null"); 136 return; 137 } 138 const auto& option = context->GetExplicitAnimationOption(); 139 if (option.IsValid()) { 140 transformAnimation_.SetEvaluator(evaluator->CreateTransformOperationsEvaluator()); 141 transformAnimation_.SetAnimationStopCallback([weak = AceType::WeakClaim(this)]() { 142 auto renderNode = weak.Upgrade(); 143 if (renderNode) { 144 renderNode->transformAnimation_.SetEvaluator(nullptr); 145 } 146 }); 147 transformAnimation_.PlayTransformAnimation(option, std::vector<TransformOperation>(), true); 148 } 149 } 150 GetTransformMatrix(const Offset & offset)151 Matrix4 GetTransformMatrix(const Offset& offset) 152 { 153 Matrix4 transform = GetTransformByOffset(UpdateWithEffectMatrix(transform_), origin_); 154 if (!offset.IsZero()) { 155 transform = GetTransformByOffset(transform, offset); 156 } 157 return transform; 158 } 159 160 // It is only used by rosenrendertransform to force conversion in clickspringeffect (avoid checking). SetPendingUpdateTransformLayer()161 virtual void SetPendingUpdateTransformLayer() {} 162 163 protected: 164 void OnTouchTestHit( 165 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 166 Matrix4 UpdateWithEffectMatrix(Matrix4 matrix); 167 void OnTransformDisappearingCallback(); 168 void ClearRenderObject() override; 169 void ParseTransformEffects(const std::vector<AnimatableTransformOperation>& transformEffects, Matrix4& transform); 170 Matrix4 ParseTransformEffect(const TransformOperation& effect); 171 void ParseDimension(TransformOperation& effect); 172 173 Matrix4 transform_; 174 bool needUpdateTransform_ = false; 175 bool isFirstAnimation_ = true; 176 AnimatableTransformOperations transformEffects_; 177 Offset origin_; 178 Dimension originX_; 179 Dimension originY_; 180 bool needUpdateOrigin_ = false; 181 double maxScaleXY_ = -1.0; 182 RefPtr<RawRecognizer> rawRecognizer_; 183 RefPtr<ClickSpringEffect> clickSpringEffect_; 184 bool disableClickEffect_ = false; 185 bool enableTouchTest_ = true; 186 Matrix4 transformPaint_; 187 TransformAnimation transformAnimation_; 188 AnimationOption transitionOption_; 189 std::vector<TransformOperation> transformEffectsAppearing_; 190 std::vector<TransformOperation> transformEffectsDisappearing_; 191 bool hasDisappearTransition_ = false; 192 bool hasAppearTransition_ = false; 193 bool pendingAppearing_ = false; 194 195 private: 196 double CovertDimensionToPxBySize(const Dimension& dimension, double size); 197 void SetTouchHandle(ClickSpringEffectType type); 198 199 #if defined(PREVIEW) 200 void ResetTransformToAccessibilityNode(); 201 void UpdateScaleToAccessibilityNode(float maxScale); 202 void UpdateTranslateToAccessibilityNode(double translateX, double translateY); 203 void UpdateRotateToAccessibilityNode(float angle, RotateAxis rotateAxis); 204 #endif 205 }; 206 207 } // namespace OHOS::Ace 208 209 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TRANSFORM_RENDER_TRANSFORM_H 210