animation_sequence_block.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/views/animation/animation_sequence_block.h"
  5. #include <map>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/callback.h"
  9. #include "base/check.h"
  10. #include "base/time/time.h"
  11. #include "base/types/pass_key.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. #include "third_party/abseil-cpp/absl/types/variant.h"
  14. #include "third_party/skia/include/core/SkColor.h"
  15. #include "ui/compositor/layer_animation_element.h"
  16. #include "ui/compositor/layer_owner.h"
  17. #include "ui/gfx/geometry/rect.h"
  18. #include "ui/gfx/geometry/rounded_corners_f.h"
  19. #include "ui/views/animation/animation_builder.h"
  20. #include "ui/views/animation/animation_key.h"
  21. namespace views {
  22. using PassKey = base::PassKey<AnimationSequenceBlock>;
  23. AnimationSequenceBlock::AnimationSequenceBlock(
  24. base::PassKey<AnimationBuilder> builder_key,
  25. AnimationBuilder* owner,
  26. base::TimeDelta start,
  27. bool repeating)
  28. : builder_key_(builder_key),
  29. owner_(owner),
  30. start_(start),
  31. repeating_(repeating) {}
  32. AnimationSequenceBlock::~AnimationSequenceBlock() {
  33. if (!finalized_) {
  34. TerminateBlock();
  35. owner_->TerminateSequence(PassKey(), repeating_);
  36. }
  37. }
  38. AnimationSequenceBlock& AnimationSequenceBlock::SetDuration(
  39. base::TimeDelta duration) {
  40. DCHECK(!finalized_) << "Do not access old blocks after creating new ones.";
  41. DCHECK(!duration_.has_value()) << "Duration may be set at most once.";
  42. duration_ = duration;
  43. return *this;
  44. }
  45. AnimationSequenceBlock& AnimationSequenceBlock::SetBounds(
  46. ui::Layer* target,
  47. const gfx::Rect& bounds,
  48. gfx::Tween::Type tween_type) {
  49. return AddAnimation({target, ui::LayerAnimationElement::BOUNDS},
  50. Element(bounds, tween_type));
  51. }
  52. AnimationSequenceBlock& AnimationSequenceBlock::SetBounds(
  53. ui::LayerOwner* target,
  54. const gfx::Rect& bounds,
  55. gfx::Tween::Type tween_type) {
  56. return SetBounds(target->layer(), bounds, tween_type);
  57. }
  58. AnimationSequenceBlock& AnimationSequenceBlock::SetBrightness(
  59. ui::Layer* target,
  60. float brightness,
  61. gfx::Tween::Type tween_type) {
  62. return AddAnimation({target, ui::LayerAnimationElement::BRIGHTNESS},
  63. Element(brightness, tween_type));
  64. }
  65. AnimationSequenceBlock& AnimationSequenceBlock::SetBrightness(
  66. ui::LayerOwner* target,
  67. float brightness,
  68. gfx::Tween::Type tween_type) {
  69. return SetBrightness(target->layer(), brightness, tween_type);
  70. }
  71. AnimationSequenceBlock& AnimationSequenceBlock::SetClipRect(
  72. ui::Layer* target,
  73. const gfx::Rect& clip_rect,
  74. gfx::Tween::Type tween_type) {
  75. return AddAnimation({target, ui::LayerAnimationElement::CLIP},
  76. Element(clip_rect, tween_type));
  77. }
  78. AnimationSequenceBlock& AnimationSequenceBlock::SetClipRect(
  79. ui::LayerOwner* target,
  80. const gfx::Rect& clip_rect,
  81. gfx::Tween::Type tween_type) {
  82. return SetClipRect(target->layer(), clip_rect, tween_type);
  83. }
  84. AnimationSequenceBlock& AnimationSequenceBlock::SetColor(
  85. ui::Layer* target,
  86. SkColor color,
  87. gfx::Tween::Type tween_type) {
  88. return AddAnimation({target, ui::LayerAnimationElement::COLOR},
  89. Element(color, tween_type));
  90. }
  91. AnimationSequenceBlock& AnimationSequenceBlock::SetColor(
  92. ui::LayerOwner* target,
  93. SkColor color,
  94. gfx::Tween::Type tween_type) {
  95. return SetColor(target->layer(), color, tween_type);
  96. }
  97. AnimationSequenceBlock& AnimationSequenceBlock::SetGrayscale(
  98. ui::Layer* target,
  99. float grayscale,
  100. gfx::Tween::Type tween_type) {
  101. return AddAnimation({target, ui::LayerAnimationElement::GRAYSCALE},
  102. Element(grayscale, tween_type));
  103. }
  104. AnimationSequenceBlock& AnimationSequenceBlock::SetGrayscale(
  105. ui::LayerOwner* target,
  106. float grayscale,
  107. gfx::Tween::Type tween_type) {
  108. return SetGrayscale(target->layer(), grayscale, tween_type);
  109. }
  110. AnimationSequenceBlock& AnimationSequenceBlock::SetOpacity(
  111. ui::Layer* target,
  112. float opacity,
  113. gfx::Tween::Type tween_type) {
  114. return AddAnimation({target, ui::LayerAnimationElement::OPACITY},
  115. Element(opacity, tween_type));
  116. }
  117. AnimationSequenceBlock& AnimationSequenceBlock::SetOpacity(
  118. ui::LayerOwner* target,
  119. float opacity,
  120. gfx::Tween::Type tween_type) {
  121. return SetOpacity(target->layer(), opacity, tween_type);
  122. }
  123. AnimationSequenceBlock& AnimationSequenceBlock::SetTransform(
  124. ui::Layer* target,
  125. gfx::Transform transform,
  126. gfx::Tween::Type tween_type) {
  127. return AddAnimation({target, ui::LayerAnimationElement::TRANSFORM},
  128. Element(std::move(transform), tween_type));
  129. }
  130. AnimationSequenceBlock& AnimationSequenceBlock::SetTransform(
  131. ui::LayerOwner* target,
  132. gfx::Transform transform,
  133. gfx::Tween::Type tween_type) {
  134. return SetTransform(target->layer(), std::move(transform), tween_type);
  135. }
  136. AnimationSequenceBlock& AnimationSequenceBlock::SetRoundedCorners(
  137. ui::Layer* target,
  138. const gfx::RoundedCornersF& rounded_corners,
  139. gfx::Tween::Type tween_type) {
  140. return AddAnimation({target, ui::LayerAnimationElement::ROUNDED_CORNERS},
  141. Element(rounded_corners, tween_type));
  142. }
  143. AnimationSequenceBlock& AnimationSequenceBlock::SetRoundedCorners(
  144. ui::LayerOwner* target,
  145. const gfx::RoundedCornersF& rounded_corners,
  146. gfx::Tween::Type tween_type) {
  147. return SetRoundedCorners(target->layer(), rounded_corners, tween_type);
  148. }
  149. AnimationSequenceBlock& AnimationSequenceBlock::SetGradientMask(
  150. ui::Layer* target,
  151. const gfx::LinearGradient& gradient_mask,
  152. gfx::Tween::Type tween_type) {
  153. return AddAnimation({target, ui::LayerAnimationElement::GRADIENT_MASK},
  154. Element(gradient_mask, tween_type));
  155. }
  156. AnimationSequenceBlock& AnimationSequenceBlock::SetGradientMask(
  157. ui::LayerOwner* target,
  158. const gfx::LinearGradient& gradient_mask,
  159. gfx::Tween::Type tween_type) {
  160. return SetGradientMask(target->layer(), gradient_mask, tween_type);
  161. }
  162. AnimationSequenceBlock& AnimationSequenceBlock::SetVisibility(
  163. ui::Layer* target,
  164. bool visible,
  165. gfx::Tween::Type tween_type) {
  166. return AddAnimation({target, ui::LayerAnimationElement::VISIBILITY},
  167. Element(visible, tween_type));
  168. }
  169. AnimationSequenceBlock& AnimationSequenceBlock::SetVisibility(
  170. ui::LayerOwner* target,
  171. bool visible,
  172. gfx::Tween::Type tween_type) {
  173. return SetVisibility(target->layer(), visible, tween_type);
  174. }
  175. AnimationSequenceBlock& AnimationSequenceBlock::At(
  176. base::TimeDelta since_sequence_start) {
  177. // NOTE: at the end of this function, this object is destroyed.
  178. DCHECK(!finalized_) << "Do not access old blocks after creating new ones.";
  179. TerminateBlock();
  180. finalized_ = true;
  181. // NOTE: `old_sequence` is actually the sequence block itself. Do not destruct
  182. // this object until the function end.
  183. auto old_sequence = owner_->SwapCurrentSequence(
  184. PassKey(), std::make_unique<AnimationSequenceBlock>(
  185. builder_key_, owner_, since_sequence_start, repeating_));
  186. return owner_->GetCurrentSequence();
  187. }
  188. AnimationSequenceBlock& AnimationSequenceBlock::Offset(
  189. base::TimeDelta since_last_block_start) {
  190. return At(start_ + since_last_block_start);
  191. }
  192. AnimationSequenceBlock& AnimationSequenceBlock::Then() {
  193. return Offset(duration_.value_or(base::TimeDelta()));
  194. }
  195. AnimationSequenceBlock::Element::Element(AnimationValue animation_value,
  196. gfx::Tween::Type tween_type)
  197. : animation_value_(std::move(animation_value)), tween_type_(tween_type) {}
  198. AnimationSequenceBlock::Element::~Element() = default;
  199. AnimationSequenceBlock::Element::Element(Element&&) = default;
  200. AnimationSequenceBlock::Element& AnimationSequenceBlock::Element::operator=(
  201. Element&&) = default;
  202. AnimationSequenceBlock& AnimationSequenceBlock::AddAnimation(AnimationKey key,
  203. Element element) {
  204. DCHECK(!finalized_) << "Do not access old blocks after creating new ones.";
  205. DCHECK(key.target) << "Animation targets must paint to a layer.";
  206. const auto result =
  207. elements_.insert(std::make_pair(std::move(key), std::move(element)));
  208. DCHECK(result.second) << "Animate (target, property) at most once per block.";
  209. return *this;
  210. }
  211. void AnimationSequenceBlock::TerminateBlock() {
  212. const auto duration = duration_.value_or(base::TimeDelta());
  213. for (auto& pair : elements_) {
  214. std::unique_ptr<ui::LayerAnimationElement> element;
  215. switch (pair.first.property) {
  216. case ui::LayerAnimationElement::TRANSFORM:
  217. element = ui::LayerAnimationElement::CreateTransformElement(
  218. absl::get<gfx::Transform>(std::move(pair.second.animation_value_)),
  219. duration);
  220. break;
  221. case ui::LayerAnimationElement::BOUNDS:
  222. element = ui::LayerAnimationElement::CreateBoundsElement(
  223. absl::get<gfx::Rect>(pair.second.animation_value_), duration);
  224. break;
  225. case ui::LayerAnimationElement::OPACITY:
  226. element = ui::LayerAnimationElement::CreateOpacityElement(
  227. absl::get<float>(pair.second.animation_value_), duration);
  228. break;
  229. case ui::LayerAnimationElement::VISIBILITY:
  230. element = ui::LayerAnimationElement::CreateVisibilityElement(
  231. absl::get<bool>(pair.second.animation_value_), duration);
  232. break;
  233. case ui::LayerAnimationElement::BRIGHTNESS:
  234. element = ui::LayerAnimationElement::CreateBrightnessElement(
  235. absl::get<float>(pair.second.animation_value_), duration);
  236. break;
  237. case ui::LayerAnimationElement::GRAYSCALE:
  238. element = ui::LayerAnimationElement::CreateGrayscaleElement(
  239. absl::get<float>(pair.second.animation_value_), duration);
  240. break;
  241. case ui::LayerAnimationElement::COLOR:
  242. element = ui::LayerAnimationElement::CreateColorElement(
  243. absl::get<SkColor>(pair.second.animation_value_), duration);
  244. break;
  245. case ui::LayerAnimationElement::CLIP:
  246. element = ui::LayerAnimationElement::CreateClipRectElement(
  247. absl::get<gfx::Rect>(pair.second.animation_value_), duration);
  248. break;
  249. case ui::LayerAnimationElement::ROUNDED_CORNERS:
  250. element = ui::LayerAnimationElement::CreateRoundedCornersElement(
  251. absl::get<gfx::RoundedCornersF>(pair.second.animation_value_),
  252. duration);
  253. break;
  254. case ui::LayerAnimationElement::GRADIENT_MASK:
  255. element = ui::LayerAnimationElement::CreateGradientMaskElement(
  256. absl::get<gfx::LinearGradient>(pair.second.animation_value_),
  257. duration);
  258. break;
  259. default:
  260. NOTREACHED();
  261. }
  262. element->set_tween_type(pair.second.tween_type_);
  263. owner_->AddLayerAnimationElement(PassKey(), pair.first, start_, duration,
  264. std::move(element));
  265. }
  266. owner_->BlockEndedAt(PassKey(), start_ + duration);
  267. elements_.clear();
  268. }
  269. } // namespace views