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 #include "base/geometry/animatable_matrix4.h"
17
18 #include "core/event/ace_event_helper.h"
19
20 namespace OHOS::Ace {
21
operator =(const Matrix4 & newMatrix4)22 AnimatableMatrix4& AnimatableMatrix4::operator=(const Matrix4& newMatrix4)
23 {
24 ResetAnimatableMatrix();
25 Matrix4& matrix4 = *this;
26 matrix4 = newMatrix4;
27 return *this;
28 }
29
operator =(const AnimatableMatrix4 & newMatrix4)30 AnimatableMatrix4& AnimatableMatrix4::operator=(const AnimatableMatrix4& newMatrix4)
31 {
32 SetAnimationOption(newMatrix4.GetAnimationOption());
33 auto pipelineContext = context_.Upgrade();
34 if (!animationCallback_ || !pipelineContext) {
35 Matrix4& matrix4 = *this;
36 matrix4 = newMatrix4;
37 return *this;
38 }
39 AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
40 if (explicitAnim.IsValid()) {
41 SetAnimationOption(explicitAnim);
42 AnimateTo(newMatrix4);
43 } else if (animationOption_.IsValid()) {
44 AnimateTo(newMatrix4);
45 } else {
46 ResetController();
47 Matrix4& matrix4 = *this;
48 matrix4 = newMatrix4;
49 }
50 isFirstAssign_ = false;
51 return *this;
52 }
53
MoveTo(const Matrix4 & target)54 void AnimatableMatrix4::MoveTo(const Matrix4& target)
55 {
56 Matrix4& matrix4 = *this;
57 matrix4 = target;
58 isFirstAssign_ = false;
59 }
60
AnimateTo(const Matrix4 & endValue)61 void AnimatableMatrix4::AnimateTo(const Matrix4& endValue)
62 {
63 if (isFirstAssign_) {
64 isFirstAssign_ = false;
65 Matrix4& matrix4 = *this;
66 matrix4 = endValue;
67 return;
68 }
69
70 if (*this == endValue && !evaluator_) {
71 return;
72 }
73 ResetController();
74 if (!animationController_) {
75 animationController_ = CREATE_ANIMATOR(context_);
76 }
77
78 TransformOperation operationInit;
79 TransformOperation operationEnd;
80 operationInit.type_ = TransformOperationType::MATRIX;
81 operationEnd.type_ = TransformOperationType::MATRIX;
82 operationInit.matrix4_ = static_cast<Matrix4>(*this);
83 operationEnd.matrix4_ = endValue;
84 RefPtr<CurveAnimation<TransformOperation>> animation = AceType::MakeRefPtr<CurveAnimation<TransformOperation>>(
85 operationInit, operationEnd, animationOption_.GetCurve());
86 if (evaluator_) {
87 animation->SetEvaluator(evaluator_);
88 }
89 animation->AddListener(std::bind(&AnimatableMatrix4::OnAnimationCallback, this, std::placeholders::_1));
90 animationController_->AddInterpolator(animation);
91 auto onFinishEvent = animationOption_.GetOnFinishEvent();
92 if (onFinishEvent) {
93 animationController_->AddStopListener([onFinishEvent, weakContext = context_] {
94 auto context = weakContext.Upgrade();
95 if (context) {
96 context->PostAsyncEvent(onFinishEvent, "ArkUIAnimatableMatrix4FinishEvent");
97 }
98 });
99 }
100 if (stopCallback_) {
101 animationController_->AddStopListener(stopCallback_);
102 }
103 animationController_->SetDuration(animationOption_.GetDuration());
104 animationController_->SetStartDelay(animationOption_.GetDelay());
105 animationController_->SetIteration(animationOption_.GetIteration());
106 animationController_->SetTempo(animationOption_.GetTempo());
107 animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
108 animationController_->SetFillMode(FillMode::FORWARDS);
109 animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
110 animationController_->Play();
111 }
112
ResetController()113 void AnimatableMatrix4::ResetController()
114 {
115 if (animationController_) {
116 if (!animationController_->IsStopped()) {
117 animationController_->Stop();
118 }
119 animationController_->ClearInterpolators();
120 animationController_->ClearAllListeners();
121 animationController_.Reset();
122 }
123 }
124
OnAnimationCallback(const TransformOperation & value)125 void AnimatableMatrix4::OnAnimationCallback(const TransformOperation& value)
126 {
127 Matrix4& matrix4 = *this;
128 matrix4 = value.matrix4_;
129 if (animationCallback_) {
130 animationCallback_();
131 }
132 }
133
ResetAnimatableMatrix()134 void AnimatableMatrix4::ResetAnimatableMatrix()
135 {
136 isFirstAssign_ = true;
137 animationOption_ = AnimationOption();
138 animationController_ = nullptr;
139 context_ = nullptr;
140 animationCallback_ = nullptr;
141 }
142
143 } // namespace OHOS::Ace
144