• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_dimension.h"
17 
18 #include "core/event/ace_event_helper.h"
19 
20 namespace OHOS::Ace {
operator =(const Dimension & newDimension)21 AnimatableDimension& AnimatableDimension::operator=(const Dimension& newDimension)
22 {
23     ResetAnimatableDimension();
24     Dimension& dimension = *this;
25     dimension = newDimension;
26     return *this;
27 }
28 
operator =(const CalcDimension & newDimension)29 AnimatableDimension& AnimatableDimension::operator=(const CalcDimension& newDimension)
30 {
31     ResetAnimatableDimension();
32     CalcDimension& dimension = *this;
33     dimension = newDimension;
34     return *this;
35 }
36 
operator =(const AnimatableDimension & newDimension)37 AnimatableDimension& AnimatableDimension::operator=(const AnimatableDimension& newDimension)
38 {
39     SetUnit(newDimension.Unit());
40     SetAnimationOption(newDimension.GetAnimationOption());
41     auto pipelineContext = context_.Upgrade();
42     if (!animationCallback_ || !pipelineContext) {
43         if (newDimension.Unit() == DimensionUnit::CALC) {
44             SetCalcValue(newDimension.CalcValue());
45         } else {
46             SetValue(newDimension.Value());
47         }
48         return *this;
49     }
50     AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
51     if (explicitAnim.IsValid()) {
52         SetAnimationOption(explicitAnim);
53         AnimateTo(newDimension.Value());
54     } else if (animationOption_.IsValid()) {
55         AnimateTo(newDimension.Value());
56     } else {
57         ResetController();
58         if (newDimension.Unit() == DimensionUnit::CALC) {
59             SetCalcValue(newDimension.CalcValue());
60         } else {
61             SetValue(newDimension.Value());
62         }
63     }
64     isFirstAssign_ = false;
65     return *this;
66 }
67 
AnimateTo(double endValue)68 void AnimatableDimension::AnimateTo(double endValue)
69 {
70     if (isFirstAssign_) {
71         LOGD("AnimateTo with first assign. endValue: %{public}.2f", endValue);
72         isFirstAssign_ = false;
73         SetValue(endValue);
74         return;
75     }
76     if (NearEqual(Value(), endValue) && !evaluator_) {
77         return;
78     }
79     ResetController();
80     if (!animationController_) {
81         animationController_ = AceType::MakeRefPtr<Animator>(context_);
82     }
83     RefPtr<CurveAnimation<double>> animation =
84         AceType::MakeRefPtr<CurveAnimation<double>>(Value(), endValue, animationOption_.GetCurve());
85     if (evaluator_) {
86         animation->SetEvaluator(evaluator_);
87     }
88     animation->AddListener(std::bind(&AnimatableDimension::OnAnimationCallback, this, std::placeholders::_1));
89 
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);
97             } else {
98                 LOGE("the context is null");
99             }
100         });
101     }
102     if (stopCallback_) {
103         animationController_->AddStopListener(stopCallback_);
104     }
105     animationController_->SetDuration(animationOption_.GetDuration());
106     animationController_->SetStartDelay(animationOption_.GetDelay());
107     animationController_->SetIteration(animationOption_.GetIteration());
108     animationController_->SetTempo(animationOption_.GetTempo());
109     animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
110     animationController_->SetFillMode(FillMode::FORWARDS);
111     animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
112     animationController_->Play();
113 }
114 
ResetController()115 void AnimatableDimension::ResetController()
116 {
117     if (animationController_) {
118         if (!animationController_->IsStopped()) {
119             animationController_->Stop();
120         }
121         animationController_->ClearInterpolators();
122         animationController_->ClearAllListeners();
123         animationController_.Reset();
124     }
125 }
126 
OnAnimationCallback(double value)127 void AnimatableDimension::OnAnimationCallback(double value)
128 {
129     SetValue(value);
130     if (animationCallback_) {
131         animationCallback_();
132     }
133 }
134 
MoveTo(double target)135 void AnimatableDimension::MoveTo(double target)
136 {
137     SetValue(target);
138     isFirstAssign_ = false;
139 }
140 
ResetAnimatableDimension()141 void AnimatableDimension::ResetAnimatableDimension()
142 {
143     isFirstAssign_ = true;
144     animationOption_ = AnimationOption();
145     animationController_ = nullptr;
146     context_ = nullptr;
147     animationCallback_ = nullptr;
148 }
149 } // namespace OHOS::Ace