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