Skip to content

Commit

Permalink
Ensuring easing is repeated correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
mattgperry committed Dec 13, 2024
1 parent 0e54f81 commit 1422aef
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Motion adheres to [Semantic Versioning](http://semver.org/).

Undocumented APIs should be considered internal and may change without warning.

## [11.15.0] 2024-12-13

### Added

- Add support for `repeat` in animation sequences.

## [11.14.4] 2024-12-13

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,16 +618,45 @@ describe("createAnimationsFromSequence", () => {

test("It correctly repeats keyframes once", () => {
const animations = createAnimationsFromSequence(
[[a, { x: [0, 100] }, { duration: 1, repeat: 1 }]],
[[a, { x: [0, 100] }, { duration: 1, repeat: 1, ease: "linear" }]],
undefined,
undefined,
{ spring }
)

expect(animations.get(a)!.keyframes.x).toEqual([0, 100, 0, 100])
const { duration, times } = animations.get(a)!.transition.x
const { duration, times, ease } = animations.get(a)!.transition.x
expect(duration).toEqual(2)
expect(times).toEqual([0, 0.5, 0.5, 1])
expect(ease).toEqual(["linear", "linear", "linear", "linear"])
})

test("It correctly repeats easing", () => {
const animations = createAnimationsFromSequence(
[
[
a,
{ x: [0, 50, 100] },
{ duration: 1, repeat: 1, ease: ["easeIn", "easeOut"] },
],
],
undefined,
undefined,
{ spring }
)

expect(animations.get(a)!.keyframes.x).toEqual([0, 50, 100, 0, 50, 100])
const { duration, times, ease } = animations.get(a)!.transition.x
expect(duration).toEqual(2)
expect(times).toEqual([0, 0.25, 0.5, 0.5, 0.75, 1])
expect(ease).toEqual([
"easeIn",
"easeOut",
"linear",
"easeIn",
"easeOut",
"easeIn",
])
})

test("Repeating a segment correctly places the next segment at the end", () => {
Expand Down
13 changes: 12 additions & 1 deletion packages/framer-motion/src/animation/sequence/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { compareByTime } from "./utils/sort"
import { invariant } from "motion-utils"
import { normalizeTimes } from "./utils/normalize-times"
import { calculateRepeatDuration } from "./utils/calc-repeat-duration"
import { getEasingForSegment } from "../../easing/utils/get-easing-for-segment"

const defaultSegmentEasing = "easeInOut"

Expand Down Expand Up @@ -203,18 +204,28 @@ export function createAnimationsFromSequence(

const originalKeyframes = [...valueKeyframesAsList]
const originalTimes = [...times]
ease = Array.isArray(ease) ? [...ease] : [ease]
const originalEase = [...ease]

for (let repeatIndex = 0; repeatIndex < repeat; repeatIndex++) {
valueKeyframesAsList.push(...originalKeyframes)

for (
let keyframeIndex = 0;
keyframeIndex < originalTimes.length;
keyframeIndex < originalKeyframes.length;
keyframeIndex++
) {
times.push(
originalTimes[keyframeIndex] + (repeatIndex + 1)
)
ease.push(
keyframeIndex === 0
? "linear"
: getEasingForSegment(
originalEase,
keyframeIndex - 1
)
)
}
}

Expand Down

0 comments on commit 1422aef

Please sign in to comment.