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_PICTURE_ANIMATION_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_PICTURE_ANIMATION_H 18 19 #include <list> 20 21 #include "core/animation/animation.h" 22 #include "core/animation/curve.h" 23 24 namespace OHOS::Ace { 25 26 template<typename T> 27 class PictureFrame : public AceType { 28 public: 29 PictureFrame() = default; PictureFrame(float duration,const T & pictureInfo)30 PictureFrame(float duration, const T& pictureInfo) : duration_(duration), pictureInfo_(pictureInfo) {} 31 32 ~PictureFrame() override = default; 33 GetDuration()34 float GetDuration() const 35 { 36 return duration_; 37 } GetPictureInfo()38 const T& GetPictureInfo() const 39 { 40 return pictureInfo_; 41 } 42 UpdateDurationWithScale(float scale)43 void UpdateDurationWithScale(float scale) 44 { 45 if (scale <= 0.0f) { 46 LOGE("update picture with scale failed. scale is invalid."); 47 return; 48 } 49 50 duration_ /= scale; 51 LOGD("update with scale. duration: %{public}f, scale: %{public}f", duration_, scale); 52 } 53 54 private: 55 float duration_ { 0.0f }; 56 const T pictureInfo_ {}; 57 }; 58 59 template<typename T> 60 class PictureAnimation : public Animation<T> { 61 public: 62 PictureAnimation() = default; 63 64 ~PictureAnimation() override = default; 65 66 // add picture. duration in normalized time. AddPicture(float duration,const T & pictureInfo)67 bool AddPicture(float duration, const T& pictureInfo) 68 { 69 if (duration <= NORMALIZED_DURATION_MIN || duration > NORMALIZED_DURATION_MAX) { 70 LOGE("duration time check failed. duration: %{public}f", duration); 71 return false; 72 } 73 if (pictures_.empty()) { 74 this->duration_ = 0.0f; 75 } 76 LOGD("picture animation: add picture ref, duration: %{public}f", duration); 77 pictures_.emplace_back(AceType::MakeRefPtr<Ace::PictureFrame<T>>(duration, pictureInfo)); 78 this->duration_ += duration; 79 return true; 80 } 81 ClearPictures()82 void ClearPictures() 83 { 84 this->duration_ = 0.0f; 85 pictures_.clear(); 86 } 87 GetValue()88 const T& GetValue() const override 89 { 90 return currentPicture_->GetPictureInfo(); 91 } 92 93 // if total normalized duration of all pictures not equals 1.0, scale it to 1.0 94 // usually call it after all pictures had been added. AutoScale()95 void AutoScale() 96 { 97 if (NearZero(this->duration_)) { 98 return; 99 } 100 if (pictures_.empty()) { 101 return; 102 } 103 104 // already equals to 1.0 105 if (NearEqual(this->duration_, NORMALIZED_DURATION_MAX)) { 106 return; 107 } 108 109 for (const auto& picture : pictures_) { 110 picture->UpdateDurationWithScale(this->duration_); 111 } 112 113 LOGD("auto scale. scale: %{public}f", this->duration_); 114 this->duration_ = NORMALIZED_DURATION_MAX; 115 } 116 117 private: UpdateAndNotifyPicture(const RefPtr<PictureFrame<T>> & picture)118 void UpdateAndNotifyPicture(const RefPtr<PictureFrame<T>>& picture) 119 { 120 if (!picture) { 121 LOGE("update picture is null."); 122 return; 123 } 124 if (currentPicture_ != picture) { 125 ValueListenable<T>::NotifyListener(picture->GetPictureInfo()); 126 currentPicture_ = picture; 127 } 128 } 129 OnNormalizedTimestampChanged(float normalized,bool revserse)130 void OnNormalizedTimestampChanged(float normalized, bool revserse) override 131 { 132 if (normalized < NORMALIZED_DURATION_MIN || normalized > NORMALIZED_DURATION_MAX) { 133 LOGE("normalized time check failed. normalized: %{public}f", normalized); 134 return; 135 } 136 if (pictures_.empty()) { 137 return; 138 } 139 140 float elapsedPictureTime = 0.0f; 141 for (const auto& picture : pictures_) { 142 elapsedPictureTime += picture->GetDuration(); 143 if (normalized < elapsedPictureTime) { 144 UpdateAndNotifyPicture(picture); 145 return; 146 } 147 } 148 // timestampInMillisecond larger than total picture duration 149 UpdateAndNotifyPicture(pictures_.back()); 150 } 151 152 RefPtr<PictureFrame<T>> currentPicture_ = AceType::MakeRefPtr<PictureFrame<T>>(); 153 std::list<RefPtr<PictureFrame<T>>> pictures_; 154 }; 155 156 } // namespace OHOS::Ace 157 158 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_PICTURE_ANIMATION_H 159