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