{"course":{"slug":"motion-and-audio","title":"Motion, Sound and Music","url":"https://addaly.com/learn/motion-and-audio","level":"intermediate","track":"create"},"lesson":{"slug":"hand-over-a-file","title":"Send the developer a file, not a video","url":"https://addaly.com/learn/motion-and-audio/hand-over-a-file","position":26,"of":72,"minutes":9,"answer":"If a developer cannot recolour it, pause it, or place it on a dark background, you exported the wrong format.","keyIdea":"If a developer cannot recolour it, pause it, or place it on a dark background, you exported the wrong format."},"body":{"format":"markdown","text":"## Send the developer a file, not a video\n\nA designer animates a neat loading spinner in After Effects, exports an MP4, and sends it to the developer. It cannot be used, and the reasons are worth listing because they are the whole argument.\n\nA video has a fixed size, so it blurs when scaled. It has a background, so it cannot sit on a coloured surface. Its colours are baked in, so it cannot follow a dark theme. It cannot be paused at a meaningful state, cannot be looped seamlessly at an arbitrary point, and cannot be driven by what the user is doing. And a three-second 1080p MP4 is a few hundred kilobytes where the same animation described as vectors is around ten.\n\nThe animation was not wrong. The file was.\n\n## The formats, and what each one is for\n\n**Lottie.** A JSON file that describes vector shapes and keyframes, played live by a small runtime on web, iOS and Android. It scales to any size, can be recoloured in code, can be played, paused, reversed and scrubbed, and is tiny. Exported from After Effects with the Bodymovin / LottieFiles plugin. This is the standard answer for icons, illustrations, loaders and empty-state animations.\n\n**CSS and SVG animation.** For anything simple: a transition, a spinner, a hover state, a line drawing itself with `stroke-dasharray`. No library, no file, nothing to load. Build the SVG in **Inkscape** (free) or **Figma**'s free tier and animate it in the stylesheet.\n\n**Rive.** A competing runtime built around state machines, so the motion responds to input rather than playing a fixed clip. Worth knowing about when the animation needs to react.\n\n**Video.** Correct for anything photographic, anything long, and anything using real footage. Not a defeat, just a different job.\n\n**Animated WebP or APNG.** When it must be raster and must loop without a player.\n\n## Two things that decide whether it works\n\n### The performance detail that decides whether it stutters\n\nAnimate `transform` and `opacity`. Those two can usually be handled by the browser's compositor without recalculating the page layout or repainting pixels.\n\nAnimating `width`, `height`, `top`, `left`, `margin` or `box-shadow` forces the browser to redo layout or paint on every single frame. On your laptop it looks fine. On a four-year-old Android phone it drops to something visibly juddery. This is the most common cause of web animation that works in the demo and fails on real devices.\n\nSo: to move something, use `transform: translateX()`, not `left`. To resize it, use `transform: scale()`, not `width`.\n\n### Lottie's honest limits\n\nLottie exports shape layers and their keyframes. It is not a renderer for After Effects.\n\nMost effects do not export: glows, blurs, distortions, layer styles, 3D layers, many blend modes, and expressions beyond a supported subset. They vanish silently. The export succeeds, the file plays, and the glow is not there. If you embed a raster image to work around this, the file size goes from kilobytes to hundreds of kilobytes and you have lost the main advantage.\n\nThe way to work with this is to keep the exporter's supported-feature list open while you animate, not to animate freely and export at the end. Build the glow as a shape with a gradient rather than as an effect. And test in the actual player on an actual device: the preview on the authoring site is not the same renderer as the one in the app.\n\n## Handover hygiene, and reduced motion\n\n### What to send\n\n- Name your layers. The developer will see those names.\n- Deliver at the size it will be used, or design it to be size-independent.\n- State the frame rate and the duration in the filename or a note.\n- Provide a static first frame as a fallback, for when the player fails or the animation is switched off.\n- Say explicitly whether it loops, plays once, or waits for an event.\n\n### Reduced motion is not optional\n\nA meaningful number of people turn on a system setting called \"reduce motion\" because animation makes them physically unwell. Vestibular disorders are real, and the triggers are large movements, parallax, and anything that zooms.\n\nIn CSS, wrap non-essential motion so it degrades to a fade:\n\n```css\n@media (prefers-reduced-motion: reduce) {\n  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }\n}\n```\n\nBetter than that blanket version is to write reduced alternatives deliberately for the animations that matter. Lottie players can be gated on the same media query. Native apps expose an equivalent flag.\n\nThis is accessibility, and it costs you about five minutes.\n\n## One thing to try\n\nTake an animation you have already delivered as a video. Ask whether a developer could change its colour, pause it halfway, or place it on a dark background. If the answer is no to all three, it was the wrong file, and rebuilding it as vectors is a short afternoon."},"check":{"question":"A designer builds an icon animation in After Effects using a glow effect and a track matte, exports it as a Lottie JSON, and the developer reports that the glow is simply missing in the app. Why?","options":[{"text":"The JSON was exported at a frame rate the player does not support, so some layers are being skipped.","correct":false,"tempting":"Treats a feature-support problem as a settings mismatch that could be corrected on re-export."},{"text":"The Lottie player in the app is out of date and needs upgrading to a version that renders effects.","correct":false,"tempting":"Assumes any missing capability is a version gap rather than something the file format never carried."},{"text":"The phone's GPU cannot render the glow at the required frame rate, so the player is disabling it.","correct":false,"tempting":"Blames device capability for content that was never present in the delivered file."},{"text":"Lottie describes vector shapes and their keyframes; most After Effects effects are outside the format and are dropped silently at export, so the glow has to be built as a shape or shipped as raster.","correct":true}]},"prev":{"slug":"interactive-motion","title":"Motion that responds to state","url":"https://addaly.com/learn/motion-and-audio/interactive-motion"},"next":{"slug":"the-motion-spec","title":"The specification a developer can build from","url":"https://addaly.com/learn/motion-and-audio/the-motion-spec"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Send the developer a file, not a video', in Motion, Sound and Music. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/motion-and-audio/hand-over-a-file (Accessed: 31 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Send the developer a file, not a video","courseTitle":"Motion, Sound and Music","module":{"index":3,"slug":"shipping-the-motion","title":"Shipping the motion"},"answer":null,"keyIdea":"If a developer cannot recolour it, pause it, or place it on a dark background, you exported the wrong format.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"send-the-developer-a-file-not-a-video","runs":[{"text":"Send the developer a file, not a video"}]},{"t":"p","runs":[{"text":"A designer animates a neat loading spinner in After Effects, exports an MP4, and sends it to the developer. It cannot be used, and the reasons are worth listing because they are the whole argument."}]},{"t":"p","runs":[{"text":"A video has a fixed size, so it blurs when scaled. It has a background, so it cannot sit on a coloured surface. Its colours are baked in, so it cannot follow a dark theme. It cannot be paused at a meaningful state, cannot be looped seamlessly at an arbitrary point, and cannot be driven by what the user is doing. And a three-second 1080p MP4 is a few hundred kilobytes where the same animation described as vectors is around ten."}]},{"t":"p","runs":[{"text":"The animation was not wrong. The file was."}]},{"t":"h2","id":"the-formats-and-what-each-one-is-for","runs":[{"text":"The formats, and what each one is for"}]},{"t":"p","runs":[{"text":"Lottie.","b":true},{"text":" A JSON file that describes vector shapes and keyframes, played live by a small runtime on web, iOS and Android. It scales to any size, can be recoloured in code, can be played, paused, reversed and scrubbed, and is tiny. Exported from After Effects with the Bodymovin / LottieFiles plugin. This is the standard answer for icons, illustrations, loaders and empty-state animations."}]},{"t":"p","runs":[{"text":"CSS and SVG animation.","b":true},{"text":" For anything simple: a transition, a spinner, a hover state, a line drawing itself with "},{"text":"stroke-dasharray","code":true},{"text":". No library, no file, nothing to load. Build the SVG in "},{"text":"Inkscape","b":true},{"text":" (free) or "},{"text":"Figma","b":true},{"text":"’s free tier and animate it in the stylesheet."}]},{"t":"p","runs":[{"text":"Rive.","b":true},{"text":" A competing runtime built around state machines, so the motion responds to input rather than playing a fixed clip. Worth knowing about when the animation needs to react."}]},{"t":"p","runs":[{"text":"Video.","b":true},{"text":" Correct for anything photographic, anything long, and anything using real footage. Not a defeat, just a different job."}]},{"t":"p","runs":[{"text":"Animated WebP or APNG.","b":true},{"text":" When it must be raster and must loop without a player."}]},{"t":"h2","id":"two-things-that-decide-whether-it-works","runs":[{"text":"Two things that decide whether it works"}]},{"t":"h3","id":"the-performance-detail-that-decides-whether-it-stutters","runs":[{"text":"The performance detail that decides whether it stutters"}]},{"t":"p","runs":[{"text":"Animate "},{"text":"transform","code":true},{"text":" and "},{"text":"opacity","code":true},{"text":". Those two can usually be handled by the browser’s compositor without recalculating the page layout or repainting pixels."}]},{"t":"p","runs":[{"text":"Animating "},{"text":"width","code":true},{"text":", "},{"text":"height","code":true},{"text":", "},{"text":"top","code":true},{"text":", "},{"text":"left","code":true},{"text":", "},{"text":"margin","code":true},{"text":" or "},{"text":"box-shadow","code":true},{"text":" forces the browser to redo layout or paint on every single frame. On your laptop it looks fine. On a four-year-old Android phone it drops to something visibly juddery. This is the most common cause of web animation that works in the demo and fails on real devices."}]},{"t":"p","runs":[{"text":"So: to move something, use "},{"text":"transform: translateX()","code":true},{"text":", not "},{"text":"left","code":true},{"text":". To resize it, use "},{"text":"transform: scale()","code":true},{"text":", not "},{"text":"width","code":true},{"text":"."}]},{"t":"h3","id":"lottie-s-honest-limits","runs":[{"text":"Lottie’s honest limits"}]},{"t":"p","runs":[{"text":"Lottie exports shape layers and their keyframes. It is not a renderer for After Effects."}]},{"t":"p","runs":[{"text":"Most effects do not export: glows, blurs, distortions, layer styles, 3D layers, many blend modes, and expressions beyond a supported subset. They vanish silently. The export succeeds, the file plays, and the glow is not there. If you embed a raster image to work around this, the file size goes from kilobytes to hundreds of kilobytes and you have lost the main advantage."}]},{"t":"p","runs":[{"text":"The way to work with this is to keep the exporter’s supported-feature list open while you animate, not to animate freely and export at the end. Build the glow as a shape with a gradient rather than as an effect. And test in the actual player on an actual device: the preview on the authoring site is not the same renderer as the one in the app."}]},{"t":"h2","id":"handover-hygiene-and-reduced-motion","runs":[{"text":"Handover hygiene, and reduced motion"}]},{"t":"h3","id":"what-to-send","runs":[{"text":"What to send"}]},{"t":"ul","items":[[{"text":"Name your layers. The developer will see those names."}],[{"text":"Deliver at the size it will be used, or design it to be size-independent."}],[{"text":"State the frame rate and the duration in the filename or a note."}],[{"text":"Provide a static first frame as a fallback, for when the player fails or the animation is switched off."}],[{"text":"Say explicitly whether it loops, plays once, or waits for an event."}]]},{"t":"h3","id":"reduced-motion-is-not-optional","runs":[{"text":"Reduced motion is not optional"}]},{"t":"p","runs":[{"text":"A meaningful number of people turn on a system setting called “reduce motion” because animation makes them physically unwell. Vestibular disorders are real, and the triggers are large movements, parallax, and anything that zooms."}]},{"t":"p","runs":[{"text":"In CSS, wrap non-essential motion so it degrades to a fade:"}]},{"t":"code","lang":"css","label":"CSS","text":"@media (prefers-reduced-motion: reduce) {\n  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }\n}"},{"t":"p","runs":[{"text":"Better than that blanket version is to write reduced alternatives deliberately for the animations that matter. Lottie players can be gated on the same media query. Native apps expose an equivalent flag."}]},{"t":"p","runs":[{"text":"This is accessibility, and it costs you about five minutes."}]},{"t":"h2","id":"one-thing-to-try","runs":[{"text":"One thing to try"}]},{"t":"p","runs":[{"text":"Take an animation you have already delivered as a video. Ask whether a developer could change its colour, pause it halfway, or place it on a dark background. If the answer is no to all three, it was the wrong file, and rebuilding it as vectors is a short afternoon."}]}],"check":{"question":[{"text":"A designer builds an icon animation in After Effects using a glow effect and a track matte, exports it as a Lottie JSON, and the developer reports that the glow is simply missing in the app. Why?"}],"options":[{"text":[{"text":"The JSON was exported at a frame rate the player does not support, so some layers are being skipped."}],"correct":false,"tempting":[{"text":"Treats a feature-support problem as a settings mismatch that could be corrected on re-export."}]},{"text":[{"text":"The Lottie player in the app is out of date and needs upgrading to a version that renders effects."}],"correct":false,"tempting":[{"text":"Assumes any missing capability is a version gap rather than something the file format never carried."}]},{"text":[{"text":"The phone’s GPU cannot render the glow at the required frame rate, so the player is disabling it."}],"correct":false,"tempting":[{"text":"Blames device capability for content that was never present in the delivered file."}]},{"text":[{"text":"Lottie describes vector shapes and their keyframes; most After Effects effects are outside the format and are dropped silently at export, so the glow has to be built as a shape or shipped as raster."}],"correct":true,"tempting":null}],"order":[2,3,0,1],"why":null},"prev":{"slug":"interactive-motion","title":"Motion that responds to state","minutes":10},"next":{"slug":"the-motion-spec","title":"The specification a developer can build from","minutes":9}}}