feat: 5-frame button assets + timeline/sidebar polish
Button assets
- Re-introduce button-asset type with 4 content states (normal/hover/
pressed/disabled) stored as keyframes at BUTTON_STATE_TIMES, plus a
separate hit-area editor mode.
- useButtonRuntime composable for per-instance state/disabled flags on
the main stage.
- Sidebar library lists button assets with live 80×80 thumbnails;
renderButtonThumbnail now accepts an images map so image-kind layers
inside a button render instead of producing a fully-transparent PNG.
- Compact (no-thumbnail) mode aligns button rows to the library-row
height.
Scope footer
- Button-edit mode now uses the same sidebar scope-footer pattern as
clip-edit (back button to "Main timeline" + active scope chip);
removed the inline exit button from the timeline scrub-bar.
Timeline
- Track-name column default bumped to 260px to match the assets sidebar
above it (storage key bumped to :v2 so stale values reset).
- scrub-bar z-index raised above sticky track-name columns so rows
scroll under it instead of over.
- scrub-handle flips z-index based on horizontal scroll: above
name-spacer when the playhead is in view (no half-clip at t=0),
below when the playhead has scrolled off the left edge (so the
toggle row cleanly covers it).
- name-spacer extends ±3/1px to fully cover the obscured handle.
- scrub-handle head pokes 3px above the ruler with rounded top corners
via clip-path path().
Track context menu
- Added missing i18n keys (renameScriptTrack / deleteScriptTrack /
renameScriptTrackDialog.{title,confirm}).
- Rename items show a visible pencil icon; empty .check slot removed
so items line up flush-left; toggle items place their active ✓ on
the right (kf-menu-trailing-check).
Dev HUD
- Test progress bar flips to --danger as soon as the first failure is
recorded, instead of only at the end of the run.
Regression tests
- renderButtonThumbnail: null on empty button, renders shape layers,
accepts custom images map.
- i18n: renameScriptTrack / deleteScriptTrack / dialog keys resolve.
- scrub-handle-obscured logic (visible at t=0, hidden when playhead is
scrolled off-screen, still visible when playhead is far to the
right of the scroll offset).
- Updated button state-scrubber expectations to match
BUTTON_STATE_TIMES (normal=1, hover=2, pressed=3, disabled=4) and
that hit-mode parks at normal=1 rather than 0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
31604052ca
commit
c3764201b8
16 files changed
+2560
-349
No files matched your search
@@ -67,6 +67,28 @@ export const en = {
|
||||
polygon: 'Polygon',
|
||||
freeform: 'Freeform (click to draw, Enter to finish, Esc to cancel)',
|
||||
freeformActive: 'Drawing… (Enter to finish, Esc to cancel)',
|
||||
button: 'Button (5-frame asset)',
|
||||
},
|
||||
buttons: 'Buttons',
|
||||
noButtons: 'No buttons yet',
|
||||
createButtonTooltip: 'Create new button asset',
|
||||
hitModeDisabled: 'Switch back to button states to add assets.',
|
||||
newButtonDialog: {
|
||||
title: 'New button',
|
||||
nameMessage: 'Button name:',
|
||||
defaultName: 'Button',
|
||||
next: 'Next',
|
||||
sizeMessage: 'Canvas size (width × height):',
|
||||
confirm: 'Create',
|
||||
},
|
||||
renameButtonDialog: {
|
||||
title: 'Rename button',
|
||||
confirm: 'Apply',
|
||||
},
|
||||
deleteButtonDialog: {
|
||||
title: 'Delete button?',
|
||||
message: 'The button asset will be removed. Any layers that reference it will no longer render.',
|
||||
confirm: 'Delete',
|
||||
},
|
||||
newTextDialog: {
|
||||
title: 'New text object',
|
||||
@@ -112,6 +134,7 @@ export const en = {
|
||||
text: 'Text',
|
||||
polygon: 'Polygon',
|
||||
appearance: 'Appearance',
|
||||
button: 'On Click',
|
||||
},
|
||||
polygonPoints: 'Points',
|
||||
polygonPointsHint: 'Changing the point count rewrites all keyframes; new points are inserted at the midpoint of the last edge.',
|
||||
@@ -163,6 +186,17 @@ export const en = {
|
||||
scriptTrackName: 'Script track',
|
||||
addScriptTrackTooltip: 'Create a new script track',
|
||||
scriptFrameTooltip: 'Script frame — {n} action(s)',
|
||||
buttonEditLabel: 'Editing button:',
|
||||
buttonEditExit: 'Exit',
|
||||
emptyButtonState: 'Empty state — drop shapes or images from the sidebar.',
|
||||
buttonModeStates: 'Edit button states (normal / hover / pressed / disabled)',
|
||||
buttonModeStatesShort: 'States',
|
||||
buttonModeHit: 'Edit the click hit area',
|
||||
buttonModeHitShort: 'Hit area',
|
||||
hitAreaHeader: 'Hit area',
|
||||
hitAreaHint: 'Click the canvas tools to add shapes',
|
||||
hitAreaEmpty: 'No hit shapes yet — add a rect or circle from the canvas.',
|
||||
hitTrackDelete: 'Delete hit shape',
|
||||
addKeyframeTooltip: 'Add keyframe for the selected track at the playhead',
|
||||
groupChildCount: '{n} tracks',
|
||||
groupEmpty: 'Drop tracks here',
|
||||
@@ -170,8 +204,13 @@ export const en = {
|
||||
title: 'Rename group',
|
||||
confirm: 'Apply',
|
||||
},
|
||||
renameScriptTrackDialog: {
|
||||
title: 'Rename script track',
|
||||
confirm: 'Apply',
|
||||
},
|
||||
ungroup: 'Ungroup',
|
||||
renameGroup: 'Rename group',
|
||||
renameScriptTrack: 'Rename script track',
|
||||
resizeTrackColumn: 'Drag to resize track name column',
|
||||
clipTrackName: 'Clip track',
|
||||
toggleTimeUnit: 'Toggle time unit',
|
||||
@@ -207,6 +246,7 @@ export const en = {
|
||||
unlock: 'Unlock',
|
||||
deleteLayer: 'Delete layer',
|
||||
deleteClipTrack: 'Delete clip track',
|
||||
deleteScriptTrack: 'Delete script track',
|
||||
separate: 'Separate Position and Rotation',
|
||||
rotation: 'Rotation',
|
||||
position: 'Position',
|
||||
@@ -227,9 +267,17 @@ export const en = {
|
||||
cropOff: 'Show everything',
|
||||
maskPreviewOn: 'Preview masks (render view)',
|
||||
maskPreviewOff: 'Back to edit view',
|
||||
stagePreviewOn: 'Turn stage preview on — buttons become interactive',
|
||||
stagePreviewOff: 'Turn stage preview off — buttons behave as normal assets',
|
||||
vertexCorner: 'Corner',
|
||||
vertexCurve: 'Curve (smooth)',
|
||||
vertexSplitCurve: 'Split curve',
|
||||
hit: {
|
||||
addRect: 'Add rect hit area',
|
||||
addCircle: 'Add circle hit area',
|
||||
addPolygon: 'Add polygon hit area',
|
||||
remove: 'Remove selected hit area',
|
||||
},
|
||||
},
|
||||
|
||||
settings: {
|
||||
|
||||
Reference in new issue
Block a user