diff --git a/packages/core/src/generators/hyperframes.test.ts b/packages/core/src/generators/hyperframes.test.ts index d14dae9a5d..3dff1652f8 100644 --- a/packages/core/src/generators/hyperframes.test.ts +++ b/packages/core/src/generators/hyperframes.test.ts @@ -220,6 +220,8 @@ describe("generateGsapTimelineScript", () => { expect(script).toContain("Sync media playback"); expect(script).toContain("media.currentTime"); + expect(script).toContain("Number.isFinite(parsedEnd) ? parsedEnd : Infinity"); + expect(script).not.toContain("parseFloat(media.dataset.end) || Infinity"); }); it("generates initial position sets for elements with x/y offsets", () => { diff --git a/packages/core/src/generators/hyperframes.ts b/packages/core/src/generators/hyperframes.ts index f6cd2eac4a..64a576ac91 100644 --- a/packages/core/src/generators/hyperframes.ts +++ b/packages/core/src/generators/hyperframes.ts @@ -739,7 +739,8 @@ function generateDefaultGsapAnimations( const time = tl.time(); document.querySelectorAll("video[data-start], audio[data-start]").forEach(function(media) { const start = parseFloat(media.dataset.start); - const end = parseFloat(media.dataset.end) || Infinity; + const parsedEnd = parseFloat(media.dataset.end); + const end = Number.isFinite(parsedEnd) ? parsedEnd : Infinity; const mediaTime = time - start; if (time >= start && time < end) { if (Math.abs(media.currentTime - mediaTime) > 0.1) { diff --git a/packages/parsers/src/gsapParser.test.ts b/packages/parsers/src/gsapParser.test.ts index 11b592f9ae..10ec965099 100644 --- a/packages/parsers/src/gsapParser.test.ts +++ b/packages/parsers/src/gsapParser.test.ts @@ -948,6 +948,13 @@ describe("serializeGsapAnimations", () => { expect(result).toContain("const myTimeline = gsap.timeline({ paused: true });"); expect(result).toContain('myTimeline.set("#el1"'); }); + + it("preserves a zero media end time", () => { + const result = serializeGsapAnimations([], "tl", { includeMediaSync: true }); + + expect(result).toContain("Number.isFinite(parsedEnd) ? parsedEnd : Infinity"); + expect(result).not.toContain("parseFloat(media.dataset.end) || Infinity"); + }); }); describe("validateCompositionGsap", () => { diff --git a/packages/parsers/src/gsapSerialize.ts b/packages/parsers/src/gsapSerialize.ts index d4080a5338..0a42aa005b 100644 --- a/packages/parsers/src/gsapSerialize.ts +++ b/packages/parsers/src/gsapSerialize.ts @@ -231,7 +231,8 @@ export function serializeGsapAnimations( const time = ${timelineVar}.time(); document.querySelectorAll("video[data-start], audio[data-start]").forEach(function(media) { const start = parseFloat(media.dataset.start); - const end = parseFloat(media.dataset.end) || Infinity; + const parsedEnd = parseFloat(media.dataset.end); + const end = Number.isFinite(parsedEnd) ? parsedEnd : Infinity; const mediaTime = time - start; if (time >= start && time < end) { if (Math.abs(media.currentTime - mediaTime) > 0.1) {