Skip to content

Commit ecb0a95

Browse files
committed
raw
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
1 parent 4ecadfc commit ecb0a95

1 file changed

Lines changed: 29 additions & 14 deletions

File tree

style/servo/animation.rs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -591,15 +591,16 @@ impl Animation {
591591
return;
592592
}
593593

594-
let total_progress = match self.state {
594+
// Raw progress ratio of the animation: can be negative (before start) or >1.0 (after end).
595+
let progress = match self.state {
595596
AnimationState::Running | AnimationState::Pending | AnimationState::Finished => {
596597
(now - self.started_at) / self.duration
597598
},
598599
AnimationState::Paused(progress) => progress,
599600
AnimationState::Canceled => return,
600601
};
601602

602-
if total_progress < 0.
603+
if progress < 0.
603604
&& self.fill_mode != AnimationFillMode::Backwards
604605
&& self.fill_mode != AnimationFillMode::Both
605606
{
@@ -611,9 +612,6 @@ impl Animation {
611612
{
612613
return;
613614
}
614-
let total_progress = total_progress
615-
.min(self.current_iteration_end_progress())
616-
.max(0.0);
617615

618616
// If we only need to take into account one keyframe, then exit early
619617
// in order to avoid doing more work.
@@ -623,8 +621,27 @@ impl Animation {
623621
}
624622
};
625623

624+
// Handle negative progress (before animation start) with backwards/both fill mode
625+
if progress < 0.0 {
626+
let keyframe = match self.current_direction {
627+
AnimationDirection::Normal => self.computed_steps.first().unwrap(),
628+
AnimationDirection::Reverse => self.computed_steps.last().unwrap(),
629+
_ => unreachable!(),
630+
};
631+
add_declarations_to_map(keyframe);
632+
return;
633+
}
634+
635+
// Progress clamped to the current iteration (0.0 to 1.0).
636+
let total_progress = progress.min(self.current_iteration_end_progress()).max(0.0);
637+
626638
if total_progress >= 1.0 {
627-
add_declarations_to_map(self.computed_steps.last().unwrap());
639+
let keyframe = match self.current_direction {
640+
AnimationDirection::Normal => self.computed_steps.last().unwrap(),
641+
AnimationDirection::Reverse => self.computed_steps.first().unwrap(),
642+
_ => unreachable!(),
643+
};
644+
add_declarations_to_map(keyframe);
628645
return;
629646
}
630647

@@ -662,26 +679,24 @@ impl Animation {
662679
_ => unreachable!(),
663680
}
664681

665-
debug!(
666-
"Animation::get_property_declaration_at_time: keyframe from {:?} to {:?}",
667-
prev_keyframe_index, next_keyframe_index
668-
);
669-
670682
let prev_keyframe = &self.computed_steps[prev_keyframe_index];
671683
let next_keyframe = match next_keyframe_index {
672684
Some(index) => &self.computed_steps[index],
673685
None => {
686+
add_declarations_to_map(&prev_keyframe);
674687
return;
675688
},
676689
};
677-
if total_progress < 0.0 {
690+
691+
// Detect zero interval. Prevent division by zero from percentage_between_keyframes.
692+
if Some(prev_keyframe_index) == next_keyframe_index {
678693
add_declarations_to_map(&prev_keyframe);
679694
return;
680695
}
681696

682-
// At progress 0, we need to handle step functions specially
697+
// At progress 0 (start of normal direction), we need to handle step functions specially
683698
// for "jump-both, jump-start, start" step functions.
684-
if total_progress == 0.0 {
699+
if total_progress == 0.0 && self.current_direction == AnimationDirection::Normal {
685700
if let TimingFunction::Steps(_steps, pos) = &prev_keyframe.timing_function {
686701
if *pos == StepPosition::JumpBoth
687702
|| *pos == StepPosition::JumpStart

0 commit comments

Comments
 (0)