Design on a canvas, refine on a timeline, ship production-ready CSS — or paste the animation code you already have and edit it visually. Free, local, no login.
73 animations with the CSS ready to copy — or open any of them in the editor and make it yours.
11 designed layouts — heroes, pricing tables, forms, toasts — already choreographed. Open one, change the copy and colours, export the CSS.
A product hero whose copy, buttons and panel arrive in sequence.
Three plans that pop in, with the featured column raised and hover lifts on every card.
Six tiles arriving as a wave across the grid, each lifting on hover.
Three notifications sliding in from the right, one after another.
Existing animation code becomes an editable timeline — no rebuilding it by hand.
Paste the animation CSS you already have and get it back as an editable timeline. Transforms, filters and shadows are split into individual properties, and :hover, :focus and :active rules become editable states.
Built for designers who think in canvases and engineers who ship CSS.
Paste existing @keyframes, transitions and :hover rules and get them back as an editable timeline. Anything that cannot be represented is listed, never dropped quietly.
Buttons that hover and press, tabs with a sliding indicator, accordions, navbars, modals, toasts, tooltips, spinners and skeletons — inserted with their motion already wired.
Real :hover / :focus-visible / :active rules compiled to transition, with asymmetric timing — fast press, slower release.
Infinite pan & zoom, marquee select, smart guides, snap-to-artboard, drag / resize / rotate handles.
Per-property tracks, keyframe diamonds, draggable playhead, loop, speed control and frame stepping.
Every easing from linear to spring. Drag bezier handles and watch the curve — and your animation — update live.
CSS, SCSS, Tailwind v4 and v3, React, Vue, Svelte, Angular, styled-components, Emotion, Web Component, HTML.
Bounce, Elastic, Glitch, Neon Flicker, Wipes, Iris, Draw Line, Orbit… applied at the playhead as real keyframes.
The whole scene is packed into the link itself. Nothing is uploaded, links never expire, and opening one leaves the recipient’s own work an undo away.
Groups hold groups, to any depth, and each one animates in its own right. They export as nested markup so transforms cascade exactly as designed.
Draw-on line animations via stroke-dashoffset, plus offset-path so any element can travel a curve.
Eight clip-path shapes and gradient masks with animatable parameters — wipes, irises and curtains in pure CSS.
Define design tokens, bind colours to them, and exports emit a :root block with var() references.
Run the generated CSS in a real sandboxed viewport at phone, tablet, laptop or custom size.
⌘K fuzzy-searches every layer, preset, component, property and command. Never hunt through a panel again.
Output leans on transform and opacity, adds will-change, and never animates layout when it can help it.
prefers-reduced-motion guards both animation and transition, and WCAG 2.3.1 flash warnings sit in the inspector.
Full layer tree with lock/hide, unlimited undo/redo, and autosave to your browser — nothing leaves your machine.
Every drag, every keyframe, every curve becomes clean @keyframes — with per-segment timing functions, baked spring physics, and an automatic reduced-motion guard. Copy it, or export straight to React, Vue, Svelte, Angular, Tailwind v4, styled-components and more.
.elastic-in {
transform: translate3d(180px, 100px, 0);
width: 120px;
height: 120px;
background: #6366f1;
border-radius: 20px;
animation: elastic-in-anim 1000ms linear 0ms infinite both;
will-change: transform, opacity;
}
@keyframes elastic-in-anim {
0% {
transform: translate3d(180px, 100px, 0) scale(0.2, 0.2);
opacity: 0;
animation-timing-function: ease-out;
}
2.5% {
transform: translate3d(180px, 100px, 0) scale(0.417, 0.417);
opacity: 0.161;
}
5% {
transform: translate3d(180px, 100px, 0) scale(0.717, 0.717);
opacity: 0.308;
}
7.5% {
transform: translate3d(180px, 100px, 0);
opacity: 0.445;
}
10% {
transform: translate3d(180px, 100px, 0) scale(1.2, 1.2);
opacity: 0.571;
}
12.5% {
transform: translate3d(180px, 100px, 0) scale(1.291, 1.291);
opacity: 0.685;
}
15% {
transform: translate3d(180px, 100px, 0) scale(1.283, 1.283);
opacity: 0.785;
}
17.5% {
transform: translate3d(180px, 100px, 0) scale(1.206, 1.206);
opacity: 0.87;
}
20% {
transform: translate3d(180px, 100px, 0) scale(1.1, 1.1);
opacity: 0.938;
}
22.5% {
transform: translate3d(180px, 100px, 0);
opacity: 0.983;
}
25% {
transform: translate3d(180px, 100px, 0) scale(0.929, 0.929);
opacity: 1;
}
27.5% {
transform: translate3d(180px, 100px, 0) scale(0.897, 0.897);
opacity: 1;
}
30% {
transform: translate3d(180px, 100px, 0) scale(0.9, 0.9);
opacity: 1;
}
32.5% {
transform: translate3d(180px, 100px, 0) scale(0.927, 0.927);
opacity: 1;
}
35% {
transform: translate3d(180px, 100px, 0) scale(0.965, 0.965);
opacity: 1;
}
37.5% {
transform: translate3d(180px, 100px, 0);
opacity: 1;
}
40% {
transform: translate3d(180px, 100px, 0) scale(1.025, 1.025);
opacity: 1;
}
42.5% {
transform: translate3d(180px, 100px, 0) scale(1.036, 1.036);
opacity: 1;
}
45% {
transform: translate3d(180px, 100px, 0) scale(1.035, 1.035);
opacity: 1;
}
47.5% {
transform: translate3d(180px, 100px, 0) scale(1.026, 1.026);
opacity: 1;
}
50% {
transform: translate3d(180px, 100px, 0) scale(1.012, 1.012);
opacity: 1;
}
52.5% {
transform: translate3d(180px, 100px, 0);
opacity: 1;
}
55% {
transform: translate3d(180px, 100px, 0) scale(0.991, 0.991);
opacity: 1;
}
57.5% {
transform: translate3d(180px, 100px, 0) scale(0.987, 0.987);
opacity: 1;
}
60% {
transform: translate3d(180px, 100px, 0) scale(0.988, 0.988);
opacity: 1;
}
62.5% {
transform: translate3d(180px, 100px, 0) scale(0.991, 0.991);
opacity: 1;
}
65% {
transform: translate3d(180px, 100px, 0) scale(0.996, 0.996);
opacity: 1;
}
67.5% {
transform: translate3d(180px, 100px, 0);
opacity: 1;
}
70% {
transform: translate3d(180px, 100px, 0) scale(1.003, 1.003);
opacity: 1;
}
72.5% {
transform: translate3d(180px, 100px, 0) scale(1.005, 1.005);
opacity: 1;
}
75% {
transform: translate3d(180px, 100px, 0) scale(1.004, 1.004);
opacity: 1;
}
77.5% {
transform: translate3d(180px, 100px, 0) scale(1.003, 1.003);
opacity: 1;
}
80% {
transform: translate3d(180px, 100px, 0) scale(1.002, 1.002);
opacity: 1;
}
82.5% {
transform: translate3d(180px, 100px, 0);
opacity: 1;
}
85% {
transform: translate3d(180px, 100px, 0) scale(0.999, 0.999);
opacity: 1;
}
87.5% {
transform: translate3d(180px, 100px, 0) scale(0.998, 0.998);
opacity: 1;
}
90% {
transform: translate3d(180px, 100px, 0) scale(0.998, 0.998);
opacity: 1;
}
92.5% {
transform: translate3d(180px, 100px, 0) scale(0.999, 0.999);
opacity: 1;
}
95% {
transform: translate3d(180px, 100px, 0) scale(0.999, 0.999);
opacity: 1;
}
97.5% {
transform: translate3d(180px, 100px, 0);
opacity: 1;
}
100% {
transform: translate3d(180px, 100px, 0);
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.elastic-in {
animation: none;
transition: none;
}
}Entrances, exits, attention-seekers and effects — applied to your element at the playhead, fully editable afterwards.
| MotionCraft | Hand-written CSS | JS animation libs | |
|---|---|---|---|
| Edit your existing CSS visually | |||
| Visual timeline editing | Some | ||
| Hover / focus / press states | By hand | Manual | |
| Zero runtime dependency | |||
| Spring & bounce physics in CSS | By hand | ||
| Production-ready output | Depends | ||
| Reduced-motion handling | Manual | Manual | |
| Share a link, no account | |||
| Free, local, no account | Varies |
Free, no account, no server. Everything runs and stays in your browser — your scenes autosave to localStorage. A future Pro tier may add cloud sharing and team features, but the editor stays free.
Nowhere. MotionCraft has no backend. Your work is saved locally in your browser and exported files download straight to your machine.
Yes. It favors transform/opacity, includes per-segment timing functions, bakes physics-based easings into keyframes, and can wrap everything in a prefers-reduced-motion guard.
CSS timing functions can’t express oscillation, so MotionCraft samples the physics curve and bakes it into intermediate keyframes — identical motion, zero JavaScript.
Absolutely. Everything you create and export is yours, no attribution required.
Yes — paste it into the import dialog. @keyframes become timeline tracks, transitions and :hover / :focus / :active rules become editable states, and transforms, filters and shadows are split back into individual properties. The import is lossy by nature, so anything it cannot represent — matrix transforms, gradients, multiple shadows — is listed with a reason rather than dropped silently.
The entire scene is compressed into the link’s fragment — the part of a URL browsers never send to a server. Nothing is uploaded, links do not expire, and opening one leaves the recipient’s own work a single undo away.
Every shape is built from interpolatable numbers — inset percentages, circle radii, polygon points — so the browser can tween between them. Masks are gradients whose stops move, which produces wipes and irises with no JavaScript.
The architecture was designed with these in mind — exporters are pluggable modules. They’re on the roadmap.