main
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
27d6a47b72 |
1.2.7: 6 more bundled fonts + custom-font upload + layerActiveAt parity
Built-in additions: Montserrat, Nunito, Figtree, Gabarito (sans),
Archivo Black (heavy display), Press Start 2P (pixel/retro).
Custom font upload (lib/fonts.ts):
- uploadCustomFont(file) reads .woff2/.woff/.ttf/.otf via FileReader,
registers a FontFace early so a corrupt file fails before storage,
then persists {id, label, dataUrl} to localStorage under
'animatr:customFonts'. Quota errors surface a friendly message.
- removeCustomFont(id) drops the FontFace + storage entry. If the
asset still pointed at the deleted font, the picker resets it to
System Sans on the calling side.
- AVAILABLE_FONTS becomes a ComputedRef combining BUILTIN_FONTS with
the reactive customFontsState. fontFamilyMapSnapshot() rebuilds the
{id → CSS family} map per export so user-uploaded fonts make it
into the exported runtime.
FontPicker UI:
- Two sections divided by a thin rule — built-ins on top, "Your fonts"
below — plus an "Upload font…" entry at the bottom that opens a
hidden file input. Custom rows show a trash button on hover.
- Auto-selects a freshly uploaded font.
Engine source becomes a function (engineSource()) instead of a const,
so each export materializes the latest FONT_FAMILY map. ENGINE_TEMPLATE
holds the static skeleton with a __FONT_FAMILY_MAP__ placeholder.
Example HTML hint:
- Built-in fonts list their .woff2 path; custom fonts get a
"locally uploaded; @font-face below has the file inlined as a data
URL" line. The fontFaceCss snippet inlines data URLs for custom
entries so it's self-contained.
Bug fixes (player layerActiveAt):
- Mirrors interpolate.ts isLayerActiveAt now. The previous
`if(total<=1) return true` short-circuit made layers with a single
future keyframe visible at t=0; the lastHold→Infinity heuristic
ignored end keyframes entirely. Both regressions affected the
fullscreen preview and standalone exports. Replaced with a strict
scan: min = earliest non-end kf, max = earliest 'end' kf or +Inf.
Static layers (no normal kfs) stay always-visible.
Tests (5 new under "text font picker — model + render + export"):
- 6 new built-in ids in FONT_FAMILIES map.
- uploadCustomFont registers + persists + appears in AVAILABLE_FONTS;
removeCustomFont reverses it. Stubs FontFace and document.fonts.add
for the test environment via a stubFontFaceForTest() helper.
- uploadCustomFont rejects unsupported extensions.
- Exported runtime FONT_FAMILIES includes uploaded custom font ids.
- FontPicker popover shows the Upload font… entry.
- New "exported runtime layerActiveAt mirrors editor isLayerActiveAt"
extracts the function from engineSource() and exercises five
scenarios (single future kf, two normal kfs no end, end kf cuts
off, static layer always-visible, end kf wins over separated tracks).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
4c2b7c7c35 |
1.2.5: text font picker + 7 bundled Google fonts + default text fill black
- New src/lib/fonts.ts: curated set (Inter, Roboto, Lora, Playfair Display, Bebas Neue, Source Code Pro, Permanent Marker) shipped as local .woff2 in public/fonts/. loadFonts() registers them via FontFace at app start; fontsReady ref re-triggers Konva text configs once fonts resolve so the first paint isn't stuck on the fallback. - TextAsset gets optional fontFamily (id; undefined = system sans). PropertiesPanel adds a font dropdown next to font size. - All five render sites read the family: CanvasStage textConfig + clipTextConfig (Konva), drawLayer + drawMaskShape (canvas2d), exportPlayer engine (uses an embedded FONT_FAMILIES map and fontFam helper; runtime version 27 → 28). - Example HTML export now lists used bundled fonts and prints the @font-face CSS the user has to paste alongside the .woff2 files — fonts themselves are NOT bundled into the export to keep it small. - Default text fill changed from yellow #f5d76e to black #000000 in both the main sidebar and the SVG-scope add-text path. - 8 new tests under "text font picker — model + render + export". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
354dd8a4f0 |
0.12.0: document drawer redesign, PWA install, clip/audio context menus + push-cascade
- Document drawer slides out from under the topbar (no tab, no hover peek); opens via project-name button, closes on outside-click or ESC. Layout: inputs row + divider + preset row, presets user-managed via popup and persisted in localStorage. - PWA manifest + minimal service worker so Chrome installs RUWIO as a standalone app — suppresses the native fullscreen exit overlay. - Clips and audio clips get right-click context menus (Duplicate / Delete) via new `duplicateClipInstance` / `duplicateAudioClip` store actions. - Clip moves cascade non-overlap in both directions; `setAudioClipPosition` now pushes backward as well as forward. New `setClipInstancePosition` gives clip instances the same behaviour. - Library drags carry timeline-shaped ghost previews (audio pill, clip pill, button thumb) instead of the library row; clip lane renders a dashed drop-target ghost and rejects window-overlap drops. - Scene / Clipart drawer tabs disappear in fullscreen; the 24 px they occupied is reclaimed for the stage. Play button sits on the exact horizontal center via a 3-column grid in the transport cluster. - Tests: context menu + push-cascade + duplicate action coverage for both clip kinds; DocumentDrawer suite rewritten for the slide-out model. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
1d84c34c15 |
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> |