123b3eb3cSopenharmony_ci/* 223b3eb3cSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License. 523b3eb3cSopenharmony_ci * You may obtain a copy of the License at 623b3eb3cSopenharmony_ci * 723b3eb3cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 823b3eb3cSopenharmony_ci * 923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and 1323b3eb3cSopenharmony_ci * limitations under the License. 1423b3eb3cSopenharmony_ci */ 1523b3eb3cSopenharmony_ci 1623b3eb3cSopenharmony_ci#ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_FLOAT_H 1723b3eb3cSopenharmony_ci#define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_FLOAT_H 1823b3eb3cSopenharmony_ci 1923b3eb3cSopenharmony_ci#include "core/animation/animator.h" 2023b3eb3cSopenharmony_ci#include "core/animation/curve_animation.h" 2123b3eb3cSopenharmony_ci#include "core/components/common/properties/animation_option.h" 2223b3eb3cSopenharmony_ci#include "core/pipeline/pipeline_base.h" 2323b3eb3cSopenharmony_ci 2423b3eb3cSopenharmony_cinamespace OHOS::Ace { 2523b3eb3cSopenharmony_ci 2623b3eb3cSopenharmony_ci/* 2723b3eb3cSopenharmony_ci * AnimatableFloat is a float with AnimationOption and Animator. 2823b3eb3cSopenharmony_ci */ 2923b3eb3cSopenharmony_ciclass AnimatableFloat final { 3023b3eb3cSopenharmony_cipublic: 3123b3eb3cSopenharmony_ci AnimatableFloat() = default; 3223b3eb3cSopenharmony_ci explicit AnimatableFloat(float value, const AnimationOption& option = AnimationOption()) 3323b3eb3cSopenharmony_ci : value_(value), animationOption_(option) {} 3423b3eb3cSopenharmony_ci ~AnimatableFloat() = default; 3523b3eb3cSopenharmony_ci using RenderNodeAnimationCallback = std::function<void()>; 3623b3eb3cSopenharmony_ci 3723b3eb3cSopenharmony_ci void SetContextAndCallback(const WeakPtr<PipelineBase>& context, RenderNodeAnimationCallback&& callback) 3823b3eb3cSopenharmony_ci { 3923b3eb3cSopenharmony_ci context_ = context; 4023b3eb3cSopenharmony_ci animationCallback_ = std::move(callback); 4123b3eb3cSopenharmony_ci } 4223b3eb3cSopenharmony_ci 4323b3eb3cSopenharmony_ci float GetValue() const 4423b3eb3cSopenharmony_ci { 4523b3eb3cSopenharmony_ci return value_; 4623b3eb3cSopenharmony_ci } 4723b3eb3cSopenharmony_ci 4823b3eb3cSopenharmony_ci void SetValue(float value) 4923b3eb3cSopenharmony_ci { 5023b3eb3cSopenharmony_ci value_ = value; 5123b3eb3cSopenharmony_ci } 5223b3eb3cSopenharmony_ci 5323b3eb3cSopenharmony_ci AnimationOption GetAnimationOption() const 5423b3eb3cSopenharmony_ci { 5523b3eb3cSopenharmony_ci return animationOption_; 5623b3eb3cSopenharmony_ci } 5723b3eb3cSopenharmony_ci 5823b3eb3cSopenharmony_ci void SetAnimationOption(const AnimationOption& option) 5923b3eb3cSopenharmony_ci { 6023b3eb3cSopenharmony_ci animationOption_ = option; 6123b3eb3cSopenharmony_ci } 6223b3eb3cSopenharmony_ci 6323b3eb3cSopenharmony_ci bool operator==(const AnimatableFloat& animFloat) const 6423b3eb3cSopenharmony_ci { 6523b3eb3cSopenharmony_ci return NearEqual(value_, animFloat.GetValue()); 6623b3eb3cSopenharmony_ci } 6723b3eb3cSopenharmony_ci 6823b3eb3cSopenharmony_ci bool operator!=(const AnimatableFloat& animFloat) const 6923b3eb3cSopenharmony_ci { 7023b3eb3cSopenharmony_ci return !operator==(animFloat); 7123b3eb3cSopenharmony_ci } 7223b3eb3cSopenharmony_ci 7323b3eb3cSopenharmony_ci AnimatableFloat& operator=(const AnimatableFloat& newValue) 7423b3eb3cSopenharmony_ci { 7523b3eb3cSopenharmony_ci SetAnimationOption(newValue.GetAnimationOption()); 7623b3eb3cSopenharmony_ci auto pipelineContext = context_.Upgrade(); 7723b3eb3cSopenharmony_ci if (NearEqual(value_, std::numeric_limits<float>::max()) || NearEqual(value_, newValue.GetValue()) 7823b3eb3cSopenharmony_ci || !pipelineContext || !animationCallback_) { 7923b3eb3cSopenharmony_ci SetValue(newValue.GetValue()); 8023b3eb3cSopenharmony_ci return *this; 8123b3eb3cSopenharmony_ci } 8223b3eb3cSopenharmony_ci 8323b3eb3cSopenharmony_ci AnimationOption explicitAnim; 8423b3eb3cSopenharmony_ci if (pipelineContext) { 8523b3eb3cSopenharmony_ci explicitAnim = pipelineContext->GetExplicitAnimationOption(); 8623b3eb3cSopenharmony_ci } 8723b3eb3cSopenharmony_ci 8823b3eb3cSopenharmony_ci // Animaiton has started already in previous update call. 8923b3eb3cSopenharmony_ci if (NearEqual(animateToEndValue_, newValue.GetValue()) && explicitAnim.IsValid()) { 9023b3eb3cSopenharmony_ci LOGW("Previous animateTo end value is same as new value."); 9123b3eb3cSopenharmony_ci return *this; 9223b3eb3cSopenharmony_ci } 9323b3eb3cSopenharmony_ci 9423b3eb3cSopenharmony_ci if (explicitAnim.IsValid()) { 9523b3eb3cSopenharmony_ci SetAnimationOption(explicitAnim); 9623b3eb3cSopenharmony_ci AnimateTo(newValue.GetValue()); 9723b3eb3cSopenharmony_ci } else if (animationOption_.IsValid()) { 9823b3eb3cSopenharmony_ci AnimateTo(newValue.GetValue()); 9923b3eb3cSopenharmony_ci } else { 10023b3eb3cSopenharmony_ci SetValue(newValue.GetValue()); 10123b3eb3cSopenharmony_ci } 10223b3eb3cSopenharmony_ci return *this; 10323b3eb3cSopenharmony_ci } 10423b3eb3cSopenharmony_ci 10523b3eb3cSopenharmony_ciprivate: 10623b3eb3cSopenharmony_ci void AnimateTo(float endValue) 10723b3eb3cSopenharmony_ci { 10823b3eb3cSopenharmony_ci animateToEndValue_ = endValue; 10923b3eb3cSopenharmony_ci ResetController(); 11023b3eb3cSopenharmony_ci if (!animationController_) { 11123b3eb3cSopenharmony_ci animationController_ = CREATE_ANIMATOR(context_); 11223b3eb3cSopenharmony_ci } 11323b3eb3cSopenharmony_ci RefPtr<CurveAnimation<float>> animation = AceType::MakeRefPtr<CurveAnimation<float>>( 11423b3eb3cSopenharmony_ci GetValue(), endValue, animationOption_.GetCurve()); 11523b3eb3cSopenharmony_ci animation->AddListener(std::bind(&AnimatableFloat::OnAnimationCallback, this, std::placeholders::_1)); 11623b3eb3cSopenharmony_ci 11723b3eb3cSopenharmony_ci animationController_->AddInterpolator(animation); 11823b3eb3cSopenharmony_ci animationController_->SetDuration(animationOption_.GetDuration()); 11923b3eb3cSopenharmony_ci animationController_->SetStartDelay(animationOption_.GetDelay()); 12023b3eb3cSopenharmony_ci animationController_->Play(); 12123b3eb3cSopenharmony_ci } 12223b3eb3cSopenharmony_ci 12323b3eb3cSopenharmony_ci void ResetController() 12423b3eb3cSopenharmony_ci { 12523b3eb3cSopenharmony_ci if (animationController_) { 12623b3eb3cSopenharmony_ci if (!animationController_->IsStopped()) { 12723b3eb3cSopenharmony_ci animationController_->Stop(); 12823b3eb3cSopenharmony_ci } 12923b3eb3cSopenharmony_ci animationController_->ClearInterpolators(); 13023b3eb3cSopenharmony_ci animationController_.Reset(); 13123b3eb3cSopenharmony_ci } 13223b3eb3cSopenharmony_ci } 13323b3eb3cSopenharmony_ci 13423b3eb3cSopenharmony_ci void OnAnimationCallback(float value) 13523b3eb3cSopenharmony_ci { 13623b3eb3cSopenharmony_ci SetValue(value); 13723b3eb3cSopenharmony_ci if (animationCallback_) { 13823b3eb3cSopenharmony_ci animationCallback_(); 13923b3eb3cSopenharmony_ci } 14023b3eb3cSopenharmony_ci } 14123b3eb3cSopenharmony_ci 14223b3eb3cSopenharmony_ciprivate: 14323b3eb3cSopenharmony_ci float value_ = std::numeric_limits<float>::max(); 14423b3eb3cSopenharmony_ci AnimationOption animationOption_; 14523b3eb3cSopenharmony_ci RefPtr<Animator> animationController_; 14623b3eb3cSopenharmony_ci WeakPtr<PipelineBase> context_; 14723b3eb3cSopenharmony_ci RenderNodeAnimationCallback animationCallback_; 14823b3eb3cSopenharmony_ci float animateToEndValue_ = -1.0f; 14923b3eb3cSopenharmony_ci}; 15023b3eb3cSopenharmony_ci 15123b3eb3cSopenharmony_ci} // namespace OHOS::Ace 15223b3eb3cSopenharmony_ci 15323b3eb3cSopenharmony_ci#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_FLOAT_H 154