0.8.4: button transitions, locked groups revoke edits, UX polish
Button-state transitions - State flips on stage-preview buttons (normal / hover / pressed / disabled) now ease over 50ms instead of snapping. New `transitions` map + rAF ticker in useButtonRuntime drive a continuous sample time between BUTTON_STATE_TIMES slots; CanvasStage samples each button child at that interpolated time so keyframes at the 4 states blend smoothly. Mid-flight flips (hover → pressed while still in normal → hover) rebase from the current live sample instead of snapping. Locked groups revoke edits - Locking a layer directly or its enclosing group deselects the layer so the Properties panel can't keep editing it. Panel also splits into three branches — editable / locked / no-layer — with a dedicated locked-layer hint. - Timeline keyframe interactions (drag, dblclick-to-remove, context menu, dblclick-to-create on lane, add-kf toolbar) now consult effective lock (direct + parent group) instead of just layer.locked. Editor polish - Inactive tracks fade as a whole row (opacity 0.5) instead of per-child, so keyframes, segments, and still-frame tails stay visually proportional to their active counterparts. - Dragging a layer onto a group's track-name label now drops it INTO the group (was previously only the group-lane area). - Button assets on the stage show a pointer cursor on hover so it's obvious they're interactive. - Global CSS forces `cursor: pointer !important` on every enabled button / role="button" so scoped component styles can no longer accidentally shadow the default. - Timeline resize handle jumped above the scrub-bar (z-index 100) so the full 14px grab zone is hit-testable again. Regression tests - setTrackLocked deselect paths: direct lock, group lock with selected child, group lock with unrelated selection, unlock doesn't re-select. - duplicateKeyframeAt: props + easing + hold + bezier copied, collision refusal, unknown-id guards, separated-track routing. - Button transition runtime: no-transition baseline, mid-flight bounds, mid-transition rebase, no-op setState. - Shared composables tooltips + asset-thumbs: same ref across calls, localStorage round-trip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1d84c34c15
commit
af5f99380c
12 files changed
+401
-34
No files matched your search
@@ -1236,6 +1236,7 @@ export const useSceneStore = defineStore('scene', {
|
||||
if (layer) {
|
||||
if (locked) layer.locked = true
|
||||
else delete layer.locked
|
||||
this.deselectIfLocked()
|
||||
return
|
||||
}
|
||||
const clipTrack = this.scene.clipTracks?.find((t) => t.id === trackId)
|
||||
@@ -1254,6 +1255,31 @@ export const useSceneStore = defineStore('scene', {
|
||||
if (group) {
|
||||
if (locked) group.locked = true
|
||||
else delete group.locked
|
||||
this.deselectIfLocked()
|
||||
}
|
||||
},
|
||||
/** When a lock change makes the currently-selected layer inert
|
||||
* (directly locked or reached by a locked parent group), drop
|
||||
* the selection so the properties panel, keyboard shortcuts,
|
||||
* and Konva transformer stop offering edits that would fail
|
||||
* silently against an ignored click. */
|
||||
deselectIfLocked() {
|
||||
const id = this.selectedLayerId
|
||||
if (!id) return
|
||||
const sel = this.activeLayers.find((l) => l.id === id)
|
||||
if (!sel) {
|
||||
this.selectedLayerId = null
|
||||
return
|
||||
}
|
||||
if (sel.locked) {
|
||||
this.selectedLayerId = null
|
||||
return
|
||||
}
|
||||
for (const g of this.scene.groups ?? []) {
|
||||
if (g.locked && g.childIds.includes(id)) {
|
||||
this.selectedLayerId = null
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
setLayerEditorHidden(layerId: string, hidden: boolean) {
|
||||
|
||||
Reference in new issue
Block a user