1 /*
2 * Copyright (c) 2024 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 "core/components/common/properties/animatable_color.h"
17
18 #include "core/event/ace_event_helper.h"
19 #include "core/pipeline/pipeline_context.h"
20
21 namespace OHOS::Ace {
22
23 AnimatableColor::AnimatableColor() = default;
AnimatableColor(uint32_t value,const AnimationOption & option)24 AnimatableColor::AnimatableColor(uint32_t value, const AnimationOption& option) : Color(value)
25 {
26 animationOption_ = option;
27 }
28
AnimatableColor(const Color & color,const AnimationOption & option)29 AnimatableColor::AnimatableColor(const Color& color, const AnimationOption& option) : Color(color.GetValue())
30 {
31 animationOption_ = option;
32 }
33
34 AnimatableColor::~AnimatableColor() = default;
35
SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)36 void AnimatableColor::SetContextAndCallback(
37 const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback)
38 {
39 context_ = context;
40 animationCallback_ = callback;
41 }
42
operator =(const AnimatableColor & newColor)43 AnimatableColor& AnimatableColor::operator=(const AnimatableColor& newColor)
44 {
45 SetAnimationOption(newColor.GetAnimationOption());
46 auto pipelineContext = context_.Upgrade();
47 if (!pipelineContext || !animationCallback_) {
48 SetValue(newColor.GetValue());
49 return *this;
50 }
51 AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
52 if (explicitAnim.IsValid()) {
53 SetAnimationOption(explicitAnim);
54 AnimateTo(newColor.GetValue());
55 } else if (animationOption_.IsValid()) {
56 AnimateTo(newColor.GetValue());
57 } else {
58 ResetController();
59 SetValue(newColor.GetValue());
60 }
61 isFirstAssign_ = false;
62 return *this;
63 }
64
AnimateTo(uint32_t endValue)65 void AnimatableColor::AnimateTo(uint32_t endValue)
66 {
67 if (isFirstAssign_) {
68 isFirstAssign_ = false;
69 SetValue(endValue);
70 return;
71 }
72 if (GetValue() == endValue) {
73 return;
74 }
75 ResetController();
76 if (!animationController_) {
77 animationController_ = CREATE_ANIMATOR(context_);
78 }
79
80 RefPtr<CurveAnimation<Color>> colorAnimation =
81 AceType::MakeRefPtr<CurveAnimation<Color>>(Color(GetValue()), Color(endValue), animationOption_.GetCurve());
82 colorAnimation->AddListener(std::bind(&AnimatableColor::OnAnimationCallback, this, std::placeholders::_1));
83
84 animationController_->AddInterpolator(colorAnimation);
85 auto onFinishEvent = animationOption_.GetOnFinishEvent();
86 if (onFinishEvent) {
87 animationController_->AddStopListener([onFinishEvent, weakContext = context_] {
88 auto context = weakContext.Upgrade();
89 if (context) {
90 context->PostAsyncEvent(onFinishEvent, "ArkUIAnimatableColorFinishEvent");
91 } else {
92 LOGE("the context is null");
93 }
94 });
95 }
96 animationController_->SetDuration(animationOption_.GetDuration());
97 animationController_->SetStartDelay(animationOption_.GetDelay());
98 animationController_->SetIteration(animationOption_.GetIteration());
99 animationController_->SetTempo(animationOption_.GetTempo());
100 animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
101 animationController_->SetFillMode(FillMode::FORWARDS);
102 animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
103 animationController_->Play();
104 }
105
ResetController()106 void AnimatableColor::ResetController()
107 {
108 if (animationController_) {
109 if (!animationController_->IsStopped()) {
110 animationController_->Stop();
111 }
112 animationController_->ClearInterpolators();
113 animationController_->ClearAllListeners();
114 animationController_.Reset();
115 }
116 }
117
OnAnimationCallback(const Color & color)118 void AnimatableColor::OnAnimationCallback(const Color& color)
119 {
120 SetValue(color.GetValue());
121 if (animationCallback_) {
122 animationCallback_();
123 }
124 }
125
126 } // namespace OHOS::Ace
127