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 20namespace OHOS::Ace { 21 22AnimatableMatrix4& AnimatableMatrix4::operator=(const Matrix4& newMatrix4) 23{ 24 ResetAnimatableMatrix(); 25 Matrix4& matrix4 = *this; 26 matrix4 = newMatrix4; 27 return *this; 28} 29 30AnimatableMatrix4& 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 54void AnimatableMatrix4::MoveTo(const Matrix4& target) 55{ 56 Matrix4& matrix4 = *this; 57 matrix4 = target; 58 isFirstAssign_ = false; 59} 60 61void AnimatableMatrix4::AnimateTo(const Matrix4& endValue) 62{ 63 if (isFirstAssign_) { 64 isFirstAssign_ = false; 65 Matrix4& matrix4 = *this; 66 matrix4 = endValue; 67 return; 68 } 69 70 if (*this == endValue && !evaluator_) { 71 return; 72 } 73 ResetController(); 74 if (!animationController_) { 75 animationController_ = CREATE_ANIMATOR(context_); 76 } 77 78 TransformOperation operationInit; 79 TransformOperation operationEnd; 80 operationInit.type_ = TransformOperationType::MATRIX; 81 operationEnd.type_ = TransformOperationType::MATRIX; 82 operationInit.matrix4_ = static_cast<Matrix4>(*this); 83 operationEnd.matrix4_ = endValue; 84 RefPtr<CurveAnimation<TransformOperation>> animation = AceType::MakeRefPtr<CurveAnimation<TransformOperation>>( 85 operationInit, operationEnd, animationOption_.GetCurve()); 86 if (evaluator_) { 87 animation->SetEvaluator(evaluator_); 88 } 89 animation->AddListener(std::bind(&AnimatableMatrix4::OnAnimationCallback, this, std::placeholders::_1)); 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, "ArkUIAnimatableMatrix4FinishEvent"); 97 } 98 }); 99 } 100 if (stopCallback_) { 101 animationController_->AddStopListener(stopCallback_); 102 } 103 animationController_->SetDuration(animationOption_.GetDuration()); 104 animationController_->SetStartDelay(animationOption_.GetDelay()); 105 animationController_->SetIteration(animationOption_.GetIteration()); 106 animationController_->SetTempo(animationOption_.GetTempo()); 107 animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection()); 108 animationController_->SetFillMode(FillMode::FORWARDS); 109 animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously()); 110 animationController_->Play(); 111} 112 113void AnimatableMatrix4::ResetController() 114{ 115 if (animationController_) { 116 if (!animationController_->IsStopped()) { 117 animationController_->Stop(); 118 } 119 animationController_->ClearInterpolators(); 120 animationController_->ClearAllListeners(); 121 animationController_.Reset(); 122 } 123} 124 125void AnimatableMatrix4::OnAnimationCallback(const TransformOperation& value) 126{ 127 Matrix4& matrix4 = *this; 128 matrix4 = value.matrix4_; 129 if (animationCallback_) { 130 animationCallback_(); 131 } 132} 133 134void AnimatableMatrix4::ResetAnimatableMatrix() 135{ 136 isFirstAssign_ = true; 137 animationOption_ = AnimationOption(); 138 animationController_ = nullptr; 139 context_ = nullptr; 140 animationCallback_ = nullptr; 141} 142 143} // namespace OHOS::Ace 144