File: animation_trigger.h

package info (click to toggle)
chromium 139.0.7258.127-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,096 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (152 lines) | stat: -rw-r--r-- 5,673 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright 2025 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TRIGGER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TRIGGER_H_

#include "third_party/blink/renderer/bindings/core/v8/v8_animation_trigger_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_animation_trigger_type.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_timelinerangeoffset.h"
#include "third_party/blink/renderer/core/animation/animation_timeline.h"
#include "third_party/blink/renderer/core/animation/scroll_snapshot_timeline.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"

namespace blink {

class ExecutionContext;

// The state of the animation's trigger.
// https://drafts.csswg.org/web-animations-2/#trigger-state
enum class AnimationTriggerState {
  // The initial state of the trigger. The trigger has not yet taken any action
  // on the animation.
  kIdle,
  // The last action taken by the trigger on the animation was due to entering
  // the trigger range.
  kPrimary,
  // The last action taken by the trigger on the animation was due to exiting
  // the exit range.
  kInverse,
};

class CORE_EXPORT AnimationTrigger : public ScriptWrappable {
  DEFINE_WRAPPERTYPEINFO();

 public:
  using RangeBoundary = V8UnionStringOrTimelineRangeOffset;
  using Type = V8AnimationTriggerType;
  using State = AnimationTriggerState;

  AnimationTrigger(AnimationTimeline* timeline,
                   Type type,
                   RangeBoundary* range_start,
                   RangeBoundary* range_end,
                   RangeBoundary* exit_range_start,
                   RangeBoundary* exit_range_end);
  static AnimationTrigger* Create(ExecutionContext* execution_context,
                                  AnimationTriggerOptions* options,
                                  ExceptionState& exception_state);

  Type type() { return type_; }

  AnimationTimeline* timeline() {
    return timeline_.Get() ? timeline_.Get()->ExposedTimeline() : nullptr;
  }
  AnimationTimeline* GetTimelineInternal() { return timeline_.Get(); }

  const RangeBoundary* rangeStart(ExecutionContext* execution_context);
  const RangeBoundary* rangeEnd(ExecutionContext* execution_context);
  const RangeBoundary* exitRangeStart(ExecutionContext* execution_context);
  const RangeBoundary* exitRangeEnd(ExecutionContext* execution_context);

  void setRangeBoundariesForTest(RangeBoundary* start,
                                 RangeBoundary* exit,
                                 RangeBoundary* exit_start,
                                 RangeBoundary* exit_end) {
    range_start_ = start;
    range_end_ = exit;
    exit_range_start_ = exit_start;
    exit_range_end_ = exit_end;
  }

  State GetState() { return state_; }

  void Trace(Visitor* visitor) const override {
    visitor->Trace(timeline_);
    visitor->Trace(range_start_);
    visitor->Trace(range_end_);
    visitor->Trace(exit_range_start_);
    visitor->Trace(exit_range_end_);
    visitor->Trace(animations_);
    ScriptWrappable::Trace(visitor);
  }

  using TimelineState = ScrollSnapshotTimeline::TimelineState;

  static Type ToV8TriggerType(EAnimationTriggerType type) {
    switch (type) {
      case EAnimationTriggerType::kOnce:
        return Type(Type::Enum::kOnce);
      case EAnimationTriggerType::kRepeat:
        return Type(Type::Enum::kRepeat);
      case EAnimationTriggerType::kAlternate:
        return Type(Type::Enum::kAlternate);
      case EAnimationTriggerType::kState:
        return Type(Type::Enum::kState);
      default:
        NOTREACHED();
    };
  }

  // Structure representing the scroll offsets (in px) corresponding to the
  // boundaries of the trigger (default) range and the exit range;
  struct TriggerBoundaries {
    // The start offset of the trigger/default range.
    double start;
    // The end offset of the trigger/default range.
    double end;
    // The start offset of the exit range.
    double exit_start;
    // The end offset of the exit range.
    double exit_end;
    double current_offset;
  };

  enum class UpdateType { kNone, kPlay, kPause, kReverse, kUnpause, kReset };

  TriggerBoundaries ComputeTriggerBoundaries(double current_offset,
                                             Element& timeline_source,
                                             const ScrollTimeline& timeline);
  std::optional<AnimationTrigger::TriggerBoundaries>
  CalculateTriggerBoundaries();
  std::optional<AnimationTrigger::State> ComputeState();

  void addAnimation(Animation* animation, ExceptionState& exception_state);
  void removeAnimation(Animation* animation);

  void Update();
  void UpdateInternal(State old_state, State new_state);
  void UpdateAnimations(UpdateType update_type);

 private:
  // Handles playing an animation which is added to a trigger which has already
  // tripped.
  void HandlePostTripAdd(Animation* animation, ExceptionState& exception_state);

  Member<AnimationTimeline> timeline_;
  Type type_;
  // The range boundaries at which the trigger takes action, in CSS pixels.
  Member<const RangeBoundary> range_start_;
  Member<const RangeBoundary> range_end_;
  Member<const RangeBoundary> exit_range_start_;
  Member<const RangeBoundary> exit_range_end_;

  State state_;
  HeapHashSet<WeakMember<Animation>> animations_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TRIGGER_H_