Repository navigation
fix(studio): plain elements keep their place and size when keyframed #5045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
c605a79
test(studio): bench a plain element animated through auto-record and …
miguel-heygen 8383bfa
fix(studio): seed a first tween from the offset a plain move left in …
miguel-heygen d01d5d6
test(studio): bench resize then drag on a GSAP tween, root and nested
miguel-heygen 0e3b4f9
fix(studio): a resize under auto-record keys size at the playhead, he…
miguel-heygen acfaced
fix(studio): keyframe tweens Studio writes end on their last key, so …
miguel-heygen 41d2a58
test(studio): keep the plain-to-keyframes moves inside the nested frame
miguel-heygen 0fb90b8
fix(studio): a resize moves its anchor from the drag stamp it read at…
miguel-heygen a9cf379
fix(studio): an undo shown in place is no longer replaced by an older…
miguel-heygen aac53ba
refactor: split the trailing keyframe trim and drop an unused GSAP re…
miguel-heygen 5f2c542
test(studio): settle the resize-then-drag bench steps so a two-save r…
miguel-heygen 8fb18d6
fix(studio): a preview reload waits for an undo shown before its writ…
miguel-heygen f0037c8
fix(studio): Add keyframe reads a subtracted calc() translate with it…
miguel-heygen 3270963
refactor: tidy the keyframe hold, trim and resize code after review
miguel-heygen 99c546d
fix(parsers): the keyframe trim leaves looping, chained and relativel…
miguel-heygen 4a940cd
fix(parsers): a size hold pins only a lone key, so an edit never chan…
miguel-heygen 53ea940
fix(studio): every undo applied in place counts as a preview change, …
miguel-heygen 3c026b9
fix(studio): a resize keys size only when a move or size is keyframed…
miguel-heygen b22815f
test(studio): a bench step whose save never lands fails the case
miguel-heygen 2273dbc
fix(parsers): holds and trims change only the tweens an edit touches
miguel-heygen ebad31f
test(studio): bank the plain-to-keyframes and resize-then-drag bench …
miguel-heygen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import { describe, expect, it } from "vitest"; | ||
| import { parseGsapScriptAcorn } from "./gsapParserAcorn.js"; | ||
| import { trimTrailingKeyframeSpans } from "./gsapWriterAcorn.js"; | ||
|
|
||
| const timeline = `const tl = gsap.timeline({ paused: true });\n`; | ||
| const tween = (keys: string, duration = 3, extra = "") => | ||
| `tl.to("#t", { keyframes: { ${keys} }, duration: ${duration}${extra} }, 1);`; | ||
| const shortOfEnd = tween(`"0%": { x: 300 }, "33.333%": { x: 297 }, "66.667%": { x: 48 }`); | ||
|
|
||
| const keyed = (script: string) => { | ||
| const anim = parseGsapScriptAcorn(script).animations.find((a) => a.keyframes)!; | ||
| return { | ||
| duration: anim.duration, | ||
| keys: anim.keyframes!.keyframes.map((k) => [k.percentage, k.properties.x]), | ||
| }; | ||
| }; | ||
|
|
||
| describe("trimTrailingKeyframeSpans", () => { | ||
| it("ends a tween this mutation wrote on its last key, keeping each key's time", () => { | ||
| const out = trimTrailingKeyframeSpans(timeline, timeline + shortOfEnd); | ||
| expect(keyed(out)).toEqual({ | ||
| duration: 2, | ||
| keys: [ | ||
| [0, 300], | ||
| [49.999, 297], | ||
| [100, 48], | ||
| ], | ||
| }); | ||
| }); | ||
|
|
||
| it("trims beside a static gsap.set, which no tween's length moves", () => { | ||
| const out = trimTrailingKeyframeSpans( | ||
| timeline, | ||
| `${timeline}gsap.set("#g", { x: 5 });\n${shortOfEnd}`, | ||
| ); | ||
| expect(keyed(out).duration).toBe(2); | ||
| }); | ||
|
|
||
| it("leaves a looping timeline, whose cycle the tail is part of", () => { | ||
| const looping = `const tl = gsap.timeline({ paused: true, repeat: -1 });\n`; | ||
| expect(trimTrailingKeyframeSpans(looping, looping + shortOfEnd)).toBe(looping + shortOfEnd); | ||
| }); | ||
|
|
||
| it("leaves a chained tween the mutation did not touch when it edits the link before", () => { | ||
| const chain = (x: number) => | ||
| `tl.to("#a", { x: ${x}, duration: 1 }, 0).to("#t", { keyframes: { "0%": { x: 300 }, "50%": { x: 48 } }, duration: 2 }, 1);`; | ||
| expect(trimTrailingKeyframeSpans(timeline + chain(1), timeline + chain(2))).toBe( | ||
| timeline + chain(2), | ||
| ); | ||
| }); | ||
|
|
||
| it("leaves a tween the mutation did not touch, and the bytes around it", () => { | ||
| const script = timeline + shortOfEnd; | ||
| expect(trimTrailingKeyframeSpans(script, script)).toBe(script); | ||
| }); | ||
|
|
||
| it.each([ | ||
| ["a lone key, which the hold renders", tween(`"0%": { x: 300 }`)], | ||
| ["a tween that already ends on its last key", tween(`"0%": { x: 300 }, "100%": { x: 48 }`)], | ||
| [ | ||
| "an outer ease, whose curve the tail is part of", | ||
| tween(`"0%": { x: 300 }, "50%": { x: 48 }`, 3, `, ease: "power2.in"`), | ||
| ], | ||
| [ | ||
| "a looping tween, whose tail is part of every cycle", | ||
| tween(`"0%": { x: 300 }, "50%": { x: 48 }`, 3, ", repeat: -1"), | ||
| ], | ||
| [ | ||
| "every tween when one is placed after another's end", | ||
| `${shortOfEnd}\ntl.to("#u", { opacity: 1, duration: 1 }, ">");`, | ||
| ], | ||
| ["a yoyo tween", tween(`"0%": { x: 300 }, "50%": { x: 48 }`, 3, ", yoyo: true")], | ||
| [ | ||
| "a tween whose repeat key is quoted", | ||
| tween(`"0%": { x: 300 }, "50%": { x: 48 }`, 3, `, "repeat": -1`), | ||
| ], | ||
| ["every tween when a label sits at the timeline's end", `${shortOfEnd}\ntl.addLabel("end");`], | ||
| ["every tween when the timeline is set to repeat later", `${shortOfEnd}\ntl.repeat(-1);`], | ||
| ])("leaves %s", (_, written) => { | ||
| expect(trimTrailingKeyframeSpans(timeline, timeline + written)).toBe(timeline + written); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.