1.0.2: persist editor-session UI state with the project
Canvas zoom + pan, crop / mask-preview / stage-preview / centre- crosshair overlays, and timeline snap / show-locked / displayMode / px-per-sec / auto-fit now ride along in the saved project under a new optional `editor` block. Reopening a project restores the workbench exactly how the user left it — zoom level, pan offset, HUD toggles, timeline density — instead of snapping back to defaults. Editor state lives on the store as a sibling of `this.project` rather than inside it, so `JSON.stringify(store.project)` (the undo/redo snapshot) still only captures content. The new `projectForSave` getter stitches the two on the way to disk; `loadProject` reads them back apart on the way in. Saves through App.vue, the rename flow, and IDB recents all go through `projectForSave`. CanvasStage skips its first auto-fit when a non-default canvas zoom/pan was restored so the user's exact view survives mount. Frame-based export options pick up the same source of truth for a consistent starting point. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
cd9cf91ef0
commit
647f09b287
9 files changed
+285
-19
No files matched your search
@@ -289,8 +289,18 @@ const viewportWidth = ref(0)
|
||||
// scrub-handle behind the sticky name-spacer when the playhead has
|
||||
// scrolled off the left edge of the visible ruler area.
|
||||
const scrollLeft = ref(0)
|
||||
const pxPerSec = ref(0)
|
||||
const autoFit = ref(true)
|
||||
// pxPerSec / autoFit mirror the store's editor.timeline* fields so
|
||||
// the timeline zoom / fit preference round-trips with the project
|
||||
// file. Thin writableComputed shims keep the rest of this
|
||||
// component's code (`pxPerSec.value = …`, `autoFit.value`) unchanged.
|
||||
const pxPerSec = computed<number>({
|
||||
get: () => store.editor.timelinePxPerSec,
|
||||
set: (v) => { store.editor.timelinePxPerSec = v },
|
||||
})
|
||||
const autoFit = computed<boolean>({
|
||||
get: () => store.editor.timelineAutoFit,
|
||||
set: (v) => { store.editor.timelineAutoFit = v },
|
||||
})
|
||||
|
||||
function clamp(v: number, lo: number, hi: number) {
|
||||
return Math.max(lo, Math.min(hi, v))
|
||||
@@ -314,8 +324,14 @@ const laneWidth = computed(() => duration.value * effectivePxPerSec.value)
|
||||
const totalWidth = computed(() => trackNameWidth.value + laneWidth.value)
|
||||
|
||||
type DisplayMode = 'seconds' | 'frames'
|
||||
const displayMode = ref<DisplayMode>('seconds')
|
||||
const snapEnabled = ref(true)
|
||||
const displayMode = computed<DisplayMode>({
|
||||
get: () => store.editor.timelineDisplayMode,
|
||||
set: (v) => { store.editor.timelineDisplayMode = v },
|
||||
})
|
||||
const snapEnabled = computed<boolean>({
|
||||
get: () => store.editor.timelineSnap,
|
||||
set: (v) => { store.editor.timelineSnap = v },
|
||||
})
|
||||
|
||||
|
||||
const SNAP_PX = 8
|
||||
|
||||
Reference in new issue
Block a user