0.8.3: custom tooltips, editor-hide, pack script, settings reshuffle

Tooltips
- New v-tooltip directive + TooltipHost floating panel replace the
  native title attribute across 95+ sites (topbar, timeline, sidebar,
  properties, stage overlays, fullscreen preview, export dialog,
  clipart drawer, modals). Styled dark card with a configurable
  label + optional help line for inline documentation; screen
  readers still get an aria-label when the panel is disabled.
- Settings → Interface toggle (`ruwio:tooltipsEnabled`) hides the
  visual panel for users who know the app. IconButton now routes
  its title prop through v-tooltip so every existing call site is
  tooltip-aware without churn.

Editor-hide + export filter
- New `Layer.editorHidden` flag, eye toggle per layer row, skipped
  by the Konva stage and the mask-preview canvas path but honoured
  by exports and fullscreen preview (runtime untouched).
- Export dialog gets a "Skip hidden tracks" switch that strips
  editor-hidden layers from every format (scene JS, runtime,
  example HTML, MP4, WebM) on opt-in. Disabled when the scene has
  no hidden layers.

Button editor
- `+` buttons appear on empty state slots in button-timeline rows
  and duplicate the nearest keyframe (prev by preference, next
  otherwise) onto that slot. New `duplicateKeyframeAt` store
  action carries props, easing, hold, and bezier handles across.

Stage / interaction
- Plain left-click on the empty content view pans the viewport,
  but only when the pointer isn't over a Konva shape — transformer
  handles, vertex dots, and selection boxes that extend past the
  canvas edge keep their drag.

Settings reshuffle
- Timeline tab merged into Document (Duration + FPS sit under a
  new "Timing" sub-heading). New Interface tab gathers three
  global prefs: Show tooltips, Show locked tracks, Asset
  thumbnails — driven by shared composables so the existing
  toolbar toggles stay in sync. Interface-tab CSS defensively
  resets the scoped label flex-column + uppercase rule that was
  making the toggle row look like an accident.

Project identity + UX polish
- Favicon wired up (moved to public/favicon.ico, linked from
  index.html); scripts/pack.sh packs the minimum Vue project
  (src, index.html, configs, public) into a tarball with the
  right version in the filename, and `npm run pack` drives it.
- About dialog now credits Torsten Hoeltge.

Test infra
- Progress bar turns red mid-run on the first failure: runAll
  gets an onResult callback that TestOverlay uses to push each
  result into the reactive array incrementally.
- mountComponent in the test harness registers v-tooltip on the
  isolated app instance so IconButton's aria-label contract
  actually fires under test.

Regression tests
- duplicateKeyframeAt: copy fidelity (props, easing, hold),
  collision refusal, unknown-id guards, separated-track targeting.
- Shared composables: useTooltipPref and useAssetThumbsPref both
  return the same ref across calls and persist to localStorage.
- Tooltip contract: IconButton ships `aria-label` (not title);
  live-DOM smoke tests match on aria-label selectors now.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-21 23:57:35 +02:00
1 parent a2c8e5998a
commit 1d84c34c15
33 files changed
+1185 -128

No files matched your search

+25 -2
View File
@@ -22,12 +22,18 @@ export const en = {
defaultName: 'Project {date}',
},
renameProject: 'Rename project',
renameProjectHelp:
'Click to rename. Saved projects update in place; new names apply at the next save.',
renameProjectDialog: {
title: 'Rename project',
message: 'Choose a new name for this project.',
confirm: 'Rename',
},
untitledProject: 'Untitled project',
saveProjectDirtyHelp:
'Your project has unsaved changes. Ctrl/Cmd+S writes them to browser storage.',
exportHelp:
'Save as runtime script, HTML, or video. MP4 needs the render server; WebM records in real time in the browser.',
replaceDialog: {
title: 'Replace project?',
message:
@@ -235,6 +241,7 @@ export const en = {
renameMarkerRetry: 'Try again',
stillFrameTooltip: 'Still frame {time} — holds until the next keyframe',
keyframeTooltip: 'Keyframe {time} — drag to move, right-click for options',
addKfFromPrev: 'Fill with nearest keyframe — copies the previous state\'s pose into this slot',
trimTooltip: '{name} · {duration}s{trims} · Drag edges to trim, double-click to open',
trimStart: 'Start -{value}s',
trimEnd: 'End -{value}s',
@@ -250,6 +257,8 @@ export const en = {
color: 'Color',
lock: 'Lock',
unlock: 'Unlock',
hideInEditor: 'Hide in editor (still exported)',
showInEditor: 'Show in editor',
deleteLayer: 'Delete layer',
deleteClipTrack: 'Delete clip track',
deleteScriptTrack: 'Delete script track',
@@ -290,10 +299,20 @@ export const en = {
title: 'Settings',
tab: {
document: 'Document',
timeline: 'Timeline',
clipart: 'Clipart',
interface: 'Interface',
theme: 'UI Theme',
},
timing: 'Timing',
tooltipsLabel: 'Show tooltips',
tooltipsDesc:
'Floating help text when you hover over a button or control. Turn off if you know the app well and find them distracting — screen readers still get the label.',
showLockedLabel: 'Show locked tracks',
showLockedDesc:
'When off, locked tracks disappear from the timeline and the stage. Use to focus on the layers you\'re still editing. Also togglable from the timeline toolbar.',
assetThumbsLabel: 'Asset thumbnails',
assetThumbsDesc:
'Render small previews in the Assets / Clips / Buttons panels. Turn off for a compact list when working with lots of items.',
bgVideoLabel: 'Video',
bgVideoNone: 'No background video',
bgVideoPickFile: 'Pick video file…',
@@ -346,6 +365,9 @@ export const en = {
back: 'Back',
labelWebm: 'Rendering WebM (browser, realtime)…',
labelMp4: 'Rendering MP4 (server)…',
skipHidden: 'Skip hidden tracks',
skipHiddenDesc: 'Drop layers toggled off in the editor from every format below.',
skipHiddenNone: 'No editor-hidden tracks in the scene.',
},
tests: {
@@ -389,12 +411,13 @@ export const en = {
},
about: {
openTooltip: 'About Animatr',
openTooltip: 'About RUWIO',
title: 'About {name}',
tagline: 'A timeline-based animation editor that runs in your browser.',
versionLabel: 'Version',
buildLabel: 'Build',
close: 'Close',
credit: 'Made with love by Torsten Hoeltge',
shortcutsHeading: 'Shortcuts',
shortcut: {
undo: 'Ctrl+Z',