0.10.4: button still-frames render only on their own state

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-22 18:32:18 +02:00
1 parent fcb8edbb88
commit 8895fc76ef
8 files changed
+311 -23

No files matched your search

+24 -2
View File
@@ -1138,11 +1138,33 @@ interface KfSegment {
tail?: boolean
}
function segmentsOf(kfs: Keyframe[], duration: number): KfSegment[] {
function segmentsOf(kfs: Keyframe[], duration: number, buttonMode = false): KfSegment[] {
if (kfs.length === 0) return []
const sorted = [...kfs].sort((a, b) => a.time - b.time)
const out: KfSegment[] = []
// Button-state timelines have discrete state frames rather than a
// continuous timeline. A still-frame kf only renders on its own
// state; the layer is NOT held into the following states. The
// connector line must stop at the still, not span past it.
if (buttonMode) {
for (let i = 0; i < sorted.length - 1; i++) {
const a = sorted[i]
const b = sorted[i + 1]
// Stills terminate any interpolation — no connector emerges from
// a hold kf toward the next state.
if (a.hold) continue
out.push({
id: `${a.id}>${b.id}`,
fromTime: a.time,
toTime: b.time,
easing: b.easing,
held: false,
})
}
return out
}
// Single keyframe means the layer is always visible (no animation
// range), so the line should span the entire timeline as a solid
// dim "on-stage" indicator — same treatment as a still-frame tail.
@@ -2953,7 +2975,7 @@ onBeforeUnmount(() => {
>
<span class="playhead" :style="{ left: pxFromTime(store.playhead) + 'px' }" />
<span
v-for="seg in segmentsOf(track.kfs, duration)"
v-for="seg in segmentsOf(track.kfs, duration, !!store.activeButtonAssetId)"
:key="seg.id"
class="kf-seg"
:class="[seg.held ? 'held' : `easing-${seg.easing}`, { tail: seg.tail }]"