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