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_
|