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 LOGD("AnimateTo with first assign. endValue: %{public}s", endValue.ToString().c_str());
65 isFirstAssign_ = false;
66 Matrix4& matrix4 = *this;
67 matrix4 = endValue;
68 return;
69 }
70
71 if (*this == endValue && !evaluator_) {
72 return;
73 }
74 ResetController();
75 if (!animationController_) {
76 animationController_ = AceType::MakeRefPtr<Animator>(context_);
77 }
78
79 TransformOperation operationInit;
80 TransformOperation operationEnd;
81 operationInit.type_ = TransformOperationType::MATRIX;
82 operationEnd.type_ = TransformOperationType::MATRIX;
83 operationInit.matrix4_ = static_cast<Matrix4>(*this);
84 operationEnd.matrix4_ = endValue;
85 RefPtr<CurveAnimation<TransformOperation>> animation = AceType::MakeRefPtr<CurveAnimation<TransformOperation>>(
86 operationInit, operationEnd, animationOption_.GetCurve());
87 if (evaluator_) {
88 animation->SetEvaluator(evaluator_);
89 }
90 animation->AddListener(std::bind(&AnimatableMatrix4::OnAnimationCallback, this, std::placeholders::_1));
91 animationController_->AddInterpolator(animation);
92 auto onFinishEvent = animationOption_.GetOnFinishEvent();
93 if (onFinishEvent) {
94 animationController_->AddStopListener([onFinishEvent, weakContext = context_] {
95 auto context = weakContext.Upgrade();
96 if (context) {
97 context->PostAsyncEvent(onFinishEvent);
98 } else {
99 LOGE("the context is null");
100 }
101 });
102 }
103 if (stopCallback_) {
104 animationController_->AddStopListener(stopCallback_);
105 }
106 animationController_->SetDuration(animationOption_.GetDuration());
107 animationController_->SetStartDelay(animationOption_.GetDelay());
108 animationController_->SetIteration(animationOption_.GetIteration());
109 animationController_->SetTempo(animationOption_.GetTempo());
110 animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
111 animationController_->SetFillMode(FillMode::FORWARDS);
112 animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
113 animationController_->Play();
114 }
115
ResetController()116 void AnimatableMatrix4::ResetController()
117 {
118 if (animationController_) {
119 if (!animationController_->IsStopped()) {
120 animationController_->Stop();
121 }
122 animationController_->ClearInterpolators();
123 animationController_->ClearAllListeners();
124 animationController_.Reset();
125 }
126 }
127
OnAnimationCallback(const TransformOperation & value)128 void AnimatableMatrix4::OnAnimationCallback(const TransformOperation& value)
129 {
130 Matrix4& matrix4 = *this;
131 matrix4 = value.matrix4_;
132 if (animationCallback_) {
133 animationCallback_();
134 }
135 }
136
ResetAnimatableMatrix()137 void AnimatableMatrix4::ResetAnimatableMatrix()
138 {
139 isFirstAssign_ = true;
140 animationOption_ = AnimationOption();
141 animationController_ = nullptr;
142 context_ = nullptr;
143 animationCallback_ = nullptr;
144 }
145
146 } // namespace OHOS::Ace
147