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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATABLE_TRANSFORM_OPERATION_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATABLE_TRANSFORM_OPERATION_H 18 19 #include <list> 20 #include <vector> 21 22 #include "base/geometry/transform_util.h" 23 #include "core/animation/animatable_base.h" 24 25 namespace OHOS::Ace { 26 27 class ACE_EXPORT AnimatableTransformOperation final : public AnimatableBase<TransformOperation> { 28 public: 29 explicit AnimatableTransformOperation(const AnimationOption& animationOption = AnimationOption()) 30 { 31 animationOption_ = animationOption; 32 } 33 explicit AnimatableTransformOperation( 34 const TransformOperation& operation, const AnimationOption& animationOption = AnimationOption()) 35 { 36 animationOption_ = animationOption; 37 SetCurrentValue(operation); 38 } 39 ~AnimatableTransformOperation() override = default; 40 MoveTo(const TransformOperation & value)41 void MoveTo(const TransformOperation& value) override 42 { 43 SetCurrentValue(value); 44 } 45 46 private: OnAnimationCallback(const TransformOperation & value)47 void OnAnimationCallback(const TransformOperation& value) override 48 { 49 SetCurrentValue(value); 50 AnimatableBase<TransformOperation>::OnAnimationCallback(value); 51 } 52 SetCurrentValue(const TransformOperation & other)53 void SetCurrentValue(const TransformOperation& other) 54 { 55 auto pipelineContext = context_.Upgrade(); 56 if (pipelineContext && pipelineContext->GetIsDeclarative() && type_ != TransformOperationType::UNDEFINED && 57 type_ != other.type_) { 58 LOGE("SetCurrentValue failed, not same type"); 59 return; 60 } 61 TransformOperation& self = *this; 62 self = other; 63 } 64 }; 65 66 class AnimatableTransformOperations final { 67 public: 68 AnimatableTransformOperations() = default; 69 AnimatableTransformOperations(const AnimatableTransformOperations& other) = default; 70 ~AnimatableTransformOperations() = default; 71 SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)72 void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback) 73 { 74 context_ = context; 75 animationCallback_ = callback; 76 } 77 GetOperations()78 const std::vector<AnimatableTransformOperation>& GetOperations() const 79 { 80 return operations_; 81 } 82 83 void AddTransformOperation( 84 const TransformOperation& operation, const AnimationOption& animationOption = AnimationOption()) 85 { 86 operations_.emplace_back(operation, animationOption); 87 } 88 Clear()89 void Clear() 90 { 91 operations_.clear(); 92 } 93 94 AnimatableTransformOperations& operator=(const AnimatableTransformOperations& other) 95 { 96 if (isFirstAssign_) { 97 operations_ = other.operations_; 98 isFirstAssign_ = false; 99 } else { 100 auto pipelineContext = context_.Upgrade(); 101 if (!pipelineContext) { 102 LOGE("AnimatableTransformOperations pipelineContext is null!"); 103 operations_ = other.operations_; 104 return *this; 105 } 106 const auto& explicitOption = pipelineContext->GetExplicitAnimationOption(); 107 if (other.operations_.size() == operations_.size()) { 108 for (std::size_t i = 0; i < operations_.size(); i++) { 109 if (explicitOption.IsValid()) { 110 operations_[i].SetAnimationOption(explicitOption); 111 } else { 112 operations_[i].SetAnimationOption(other.operations_[i].GetAnimationOption()); 113 } 114 operations_[i].SetContextAndCallback(context_, animationCallback_); 115 operations_[i].AnimateTo(operations_[i], other.operations_[i]); 116 } 117 } else { 118 LOGE("AddTransformOperation %{public}d != %{public}d", static_cast<int32_t>(operations_.size()), 119 static_cast<int32_t>(other.operations_.size())); 120 operations_ = other.operations_; 121 } 122 } 123 return *this; 124 } 125 126 private: 127 std::vector<AnimatableTransformOperation> operations_; 128 RenderNodeAnimationCallback animationCallback_; 129 WeakPtr<PipelineContext> context_; 130 bool isFirstAssign_ = true; 131 }; 132 133 class TransformAnimation final : public AnimatableBase<TransformOperations> { 134 public: ComputerBlendedMatrix4()135 Matrix4 ComputerBlendedMatrix4() 136 { 137 TransformOperations::ParseOperationsToMatrix(blended.GetOperations()); 138 return blended.ComputerRemaining(0); 139 } 140 SetTransformOperations(const std::vector<TransformOperation> & other)141 void SetTransformOperations(const std::vector<TransformOperation>& other) 142 { 143 operations_ = other; 144 blended = TransformOperations(operations_); 145 endValue_ = blended; 146 } 147 148 void PlayTransformAnimation( 149 const AnimationOption& option, const std::vector<TransformOperation>& other, bool alwaysRotate = false) 150 { 151 SetAnimationOption(option); 152 auto target = TransformOperations(other); 153 TransformOperations::ParseOperationsToMatrix(operations_); 154 TransformOperations::ParseOperationsToMatrix(target.GetOperations()); 155 target.SetAlwaysRotate(alwaysRotate); 156 AnimateTo(blended, target); 157 // just move to target, renderNode should use blended to computer matrix 158 MoveTo(target); 159 } 160 MoveTo(const TransformOperations & value)161 void MoveTo(const TransformOperations& value) override 162 { 163 operations_ = value.GetOperations(); 164 } 165 166 private: OnAnimationCallback(const TransformOperations & value)167 void OnAnimationCallback(const TransformOperations& value) override 168 { 169 blended = value; 170 AnimatableBase<TransformOperations>::OnAnimationCallback(value); 171 } 172 173 private: 174 TransformOperations blended; 175 }; 176 177 } // namespace OHOS::Ace 178 179 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATABLE_TRANSFORM_OPERATION_H 180