kawaandClaude Opus 5 fe57429603 fix: crop rotated images, radius in px, modals block timeline
Replays the 13 open bug reports on alyssaxuu/motionity against this fork.
Nine were already fixed by the earlier audit and one (#8, video from the
search tab) needs a Pixabay API key to reproduce; these are the three that
were still broken.

#23 - border radius behaved like a percentage. fabric applies rx/ry before
the object's scale and shapes are resized by scaling, so a radius typed as
20 drew at 60px on a rect scaled 3x while the panel still read 20. A new
cornerRadius property keeps the pixel value the user asked for, rx/ry are
derived from it and re-derived whenever the scale changes, and old projects
fall back to rx * scaleX.

#27 - cropping a rotated image cropped the wrong region. crop() compared
canvas-space edges and covered only three of the four quadrants, so it did
nothing at all when the crop window was centred on the image. It now works
in the image's own frame, clamps the region to the bitmap and re-centres the
object on what it kept; the crop window carries the image's angle and the
expand-to-full-bitmap shift in cropImage is rotated the same way.

#1 - modals are painted over the timeline but never took its pointer events,
so the resize handle, seekbar, keyframes and layer bars all reacted to a drag
behind the dialog. All four now bail while a modal is open.

Verified in Chromium: 20px draws a 20px corner at scale 1 and scale 3 and
survives save, JSON round-trip and reload; at 0, 30 and 45 degrees the pixels
under the crop window are unchanged by the crop and everything outside it is
dropped; a real drag on the timeline handle with the export modal open leaves
the timeline height untouched. WEBM export and a non-rotated crop still work.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 17:28:50 +02:00
2026-08-13 09:04:04 +02:00
2026-08-12 12:58:07 +02:00
2026-08-11 15:58:47 +02:00
2026-08-11 15:58:47 +02:00
2026-08-13 14:05:41 +02:00

Motionity

Motionity

Web-based motion graphics editor — keyframing, masking, filters, text animations. A free alternative to After Effects and Canva, running entirely in the browser.

Try the live demo — motionity.kawa.zip

Demo License Downloads


Created by Alyssa X · maintained by Kawa

Fork of the original Motionity, with bug fixes, vendored (offline-capable) assets, desktop builds and a hardened container image.


How to run

docker compose up -d          # http://localhost:8080

Or without compose:

docker run --rm -p 8080:8080 git.azuze.fr/kawa/motionity:latest

Build the image yourself:

docker build -t motionity:latest .        # ~86 MB on disk
docker build --build-arg WITH_FFMPEG=0 .  # -23 MB, no MP4/GIF export

Runtime is static-web-server on Alpine — no Node, no shell, runs as UID 65534, read_only filesystem.

Windows app

Grab the installer or the portable build from Releases:

File What it is
Motionity Setup <ver>.exe NSIS installer, per-user, choosable install dir
Motionity-<ver>-x64.exe Portable, no install

Build from source (on Windows):

npm install
npm run dist:win              # -> dist/

Linux app

From Releases: Motionity-<ver>-x86_64.AppImage or the .flatpak.

chmod +x Motionity-*.AppImage && ./Motionity-*.AppImage   # needs libfuse2
flatpak install ./Motionity-*.flatpak                      # or this

Build from source (on Linux or WSL2):

npm install
npm run dist:appimage         # AppImage only
npm run dist:flatpak          # Flatpak only
npm run dist:linux            # both

From source — web

npm install
npm run vendor                # downloads third-party assets into src/vendor/ (~24 MB)
npm start                     # http://127.0.0.1:8080
HOST=0.0.0.0 PORT=3000 npm start     # bind elsewhere

From source — desktop

npm install
npm run vendor
npm run dev                   # Electron

In a VS Code terminal, ELECTRON_RUN_AS_NODE=1 breaks this. Unset it: $env:ELECTRON_RUN_AS_NODE=$null; npm run dev

Two things to know

  • npm run vendor is mandatory for every non-Docker target. Without it the page loads but every script 404s. The Docker build runs it inside the image.
  • Secure context required. WebCodecs (fast export) and IndexedDB (project saving) only exist on http://localhost or HTTPS. Over plain HTTP on a LAN address they silently disappear: export falls back to slow real-time capture, projects stop saving. Anything beyond localhost needs TLS — deploy/Caddyfile is the shortest path.

Full packaging details, WSL notes and troubleshooting: PACKAGING.md.


Dependencies

Everything is vendored at build time — no CDN is contacted at runtime.

Editor core

Library Role
Fabric.js canvas object model, selection, transforms
anime.js keyframe animation engine
lottie-web Lottie / Bodymovin playback
ffmpeg.wasm MP4 / GIF export (single-threaded core)
webm-writer-js WEBM muxing for the WebCodecs exporter

UI

Library Role
jQuery DOM plumbing
Pickr color picker
Selection.js timeline box-selection
Sortable layer reordering
jquery-nice-select styled <select>
range-slider timeline / property sliders (vendored, no upstream banner)
Localbase IndexedDB project storage
webfontloader Google Fonts loading
Inter UI typeface

Build & runtime

Package Role
Electron desktop shell
electron-builder NSIS / AppImage / Flatpak packaging
static-web-server container HTTP server

scripts/server.cjs (the npm start server) has zero dependencies — Node 18+ builtins only.

Still online by design

Google Fonts (font picker), Pixabay (image/video/audio search), Unsplash (empty-state samples). All three degrade quietly when offline; the editor itself starts and exports without a network.


License

MIT — same as upstream.

S
Description
This is a fork of the original project aiming to fix issues and add features.
Readme MIT
42 MiB
2026-08-14 11:00:58 +02:00
Languages
JavaScript 80.1%
PowerShell 9.1%
CSS 8%
HTML 2.6%
Dockerfile 0.2%