<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Remotion | Make videos programmatically Blog</title>
        <link>https://www.remotion.dev/learn</link>
        <description>Remotion | Make videos programmatically Blog</description>
        <lastBuildDate>Thu, 22 Dec 2022 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Recreating the Apple fireworks animation]]></title>
            <link>https://www.remotion.dev/learn/apple-wow</link>
            <guid>https://www.remotion.dev/learn/apple-wow</guid>
            <pubDate>Thu, 22 Dec 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to create an animation that Apple has on its website during the holiday season with this beginner-friendly Remotion tutorial!]]></description>
            <content:encoded><![CDATA[<script id="__doc_raw" type="application/json">"---\nslug: apple-wow\ntitle: Recreating the Apple fireworks animation\nauthors:\n  - name: Mehmet Ademi\n    title: Business Developer\n    url: https://github.com/MehmetAdemi\n    image_url: /img/team/mehmet.png\n  - name: Jonny Burger\n    title: Chief Hacker\n    url: https://github.com/JonnyBurger\n    image_url: /img/team/jonny.png\n---\n\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';\nimport {AppleFireworksTutorial} from '../src/components/tutorials';\n\nLearn how to create an animation that Apple has on its website during the holiday season with this beginner-friendly Remotion tutorial!\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Final.gif\" />\n\n## Video version\n\nThis tutorial is also available as a video version:\n\n<AppleFireworksTutorial />\n\n## Source code\n\n[GitHub](https://github.com/remotion-dev/apple-wow-tutorial)\n\n## Getting started\n\nStart a new Remotion project and select the blank template:\n\n<Tabs\ndefaultValue=\"npm\"\nvalues={[\n{ label: 'npm', value: 'npm', },\n{ label: 'yarn', value: 'yarn', },\n{ label: 'pnpm', value: 'pnpm', },\n]\n}>\n<TabItem value=\"npm\">\n\n```bash\nnpm init video --blank\n```\n\n  </TabItem>\n  <TabItem value=\"pnpm\">\n\n```bash\npnpm create video --blank\n```\n\n  </TabItem>\n\n  <TabItem value=\"yarn\">\n\n```bash\nyarn create video --blank\n```\n\n  </TabItem>\n</Tabs>\n\n## Composition setup\n\nA [`<Composition>`](https://www.remotion.dev/docs/terminology/composition) defines the dimensions and duration of the video. In the `src/Root.tsx` file, adjust the width and height to the following:\n\n```tsx twoslash title=\"src/Root.tsx\"\nimport {Composition} from 'remotion';\nexport const MyComposition: React.FC = () => null;\n// ---cut---\nexport const RemotionRoot: React.FC = () => {\n  return (\n    <>\n      <Composition id=\"MyComp\" component={MyComposition} durationInFrames={150} fps={30} width={1920} height={1080} />\n    </>\n  );\n};\n```\n\n## Create a background\n\nCreate a new file `src/Background.tsx` and return a background with linear gradient:\n\n```tsx twoslash title=\"src/Background.tsx\"\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\n\nexport const Background: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        background: 'linear-gradient(to bottom, #000021, #010024)',\n      }}\n    />\n  );\n};\n```\n\nAdd the created background to the `<MyComposition/>` component, which can be found in the file `src/Composition.tsx`. This file will contain all the components that you create in this tutorial.\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Background.tsx\nexport const Background: React.FC = () => null;\n\n// @filename: Composition.tsx\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\n// ---cut---\n\nexport const MyComposition: React.FC = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n    </AbsoluteFill>\n  );\n};\n```\n\nThis results in the following:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Background.png\" />\n\n## Render a dot\n\nRender a white dot by creating a new file `src/Dot.tsx` and return a centered circle.\n\n```tsx twoslash title=\"src/Dot.tsx\"\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\n\nexport const Dot: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        justifyContent: 'center',\n        alignItems: 'center',\n      }}\n    >\n      <div\n        style={{\n          height: 14,\n          width: 14,\n          borderRadius: 14 / 2,\n          backgroundColor: '#ccc',\n        }}\n      />\n    </AbsoluteFill>\n  );\n};\n```\n\nAdd the `<Dot>` in your main composition `src/Composition.tsx`:\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Dot.tsx\nexport const Dot: React.FC = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC = () => null;\n\n// @filename: Composition.tsx\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dot} from './Dot';\n// ---cut---\n\nexport const MyComposition: React.FC = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Dot />\n    </AbsoluteFill>\n  );\n};\n```\n\nNow we got a white dot on top of our background:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Dot.png\" />\n\n## Animate the dot\n\nLet's apply some animation to the white dot we created above. We create another component called `<Shrinking>` in a new file `src/Shrinking.tsx`, which then wraps the dot in the main composition `src/Composition.tsx`.\n\n```tsx title=\"src/Shrinking.tsx\"\nimport React from 'react';\nimport {AbsoluteFill, interpolate, useCurrentFrame} from 'remotion';\n\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = ({children}) => {\n  const frame = useCurrentFrame();\n\n  return (\n    <AbsoluteFill\n      style={{\n        scale: String(\n          interpolate(frame, [60, 90], [1, 0], {\n            extrapolateLeft: 'clamp',\n            extrapolateRight: 'clamp',\n          }),\n        ),\n      }}\n    >\n      {children}\n    </AbsoluteFill>\n  );\n};\n```\n\nAdd the `<Shrinking>` component in your main composition `src/Composition.tsx`:\n\n```tsx twoslash\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC = () => null;\n\n// @filename: Composition.tsx\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dot} from './Dot';\nimport {Shrinking} from './Shrinking';\n\n// ---cut---\n\nexport const MyComposition: React.FC = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Shrinking>\n        <Dot />\n      </Shrinking>\n    </AbsoluteFill>\n  );\n};\n```\n\nNow, you have some action to show. By using `<Shrinking>` in your main composition you have created a scale out effect:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Shrinking.gif\" />\n\n## Move the dot\n\nNext, create a component called `<Move>`. This component has a spring animation, which by default goes from zero to one, and has a duration of four seconds (`durationInFrames: 120`) in the code snippet below:\n\n```tsx twoslash title=\"src/Move.tsx\"\nimport React from 'react';\nimport {AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion';\n\nexport const Move: React.FC<{\n  children: React.ReactNode;\n}> = ({children}) => {\n  const {fps} = useVideoConfig();\n  const frame = useCurrentFrame();\n\n  const down = spring({\n    fps,\n    frame,\n    config: {\n      damping: 200,\n    },\n    durationInFrames: 120,\n  });\n\n  const y = interpolate(down, [0, 1], [0, -400]);\n\n  return (\n    <AbsoluteFill\n      style={{\n        translate: `0 ${y}px`,\n      }}\n    >\n      {children}\n    </AbsoluteFill>\n  );\n};\n```\n\nAdd the `<Move>` component to your composition `src/Composition.tsx`. You get a nice animation by combining the effect of moving and shrinking by surrounding the shrinking dot in the `<Move>` component:\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n}> = ({children}) => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC = () => null;\n\n// @filename: Composition.tsx\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dot} from './Dot';\nimport {Move} from './Move';\nimport {Shrinking} from './Shrinking';\n\n// ---cut---\n\nexport const MyComposition = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Move>\n        <Shrinking>\n          <Dot />\n        </Shrinking>\n      </Move>\n    </AbsoluteFill>\n  );\n};\n```\n\nAnd up goes the dot:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Move.gif\" />\n\n## Duplicate the moving dot\n\nHere it gets a little bit trickier, but the following steps are going to make your animation a lot more entertaining. First, you add a `delay` prop into the `<Move>` component and then change the `frame` parameter of your `spring()` function.\n\n```tsx twoslash title=\"src/Move.tsx\"\nimport React from 'react';\nimport {AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion';\n\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = ({children, delay}) => {\n  const {fps} = useVideoConfig();\n  const frame = useCurrentFrame();\n\n  const down = spring({\n    fps,\n    frame: frame - delay,\n    config: {\n      damping: 200,\n    },\n    durationInFrames: 120,\n  });\n\n  const y = interpolate(down, [0, 1], [0, -400]);\n\n  return (\n    <AbsoluteFill\n      style={{\n        translate: `0 ${y}px`,\n      }}\n    >\n      {children}\n    </AbsoluteFill>\n  );\n};\n```\n\nNow, let's create a `<Trail>` component. It takes some React children and duplicates them. The component adds a delay to each subsequent dot so they don't start all at once. Each dot will have a scale applied to it, so that each dot is smaller than the previous one.\n\nPut the previously created `<Move>` component within the `<Trail>` component.\nThe order is crucial here. Things are done from inside out:\n\n1. Apply a scale so that the dots become smaller over time.\n2. Apply the move animation.\n3. Apply a delay between the animation start of each dot by using Remotion's `<Sequence>` component.\n\n```tsx twoslash title=\"src/Trail.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n\n// @filename: Trail.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill, Sequence} from 'remotion';\nimport {Move} from './Move';\n\nexport const Trail: React.FC<{\n  amount: number;\n  children: React.ReactNode;\n}> = ({amount, children}) => {\n  return (\n    <AbsoluteFill>\n      {new Array(amount).fill(true).map((a, i) => {\n        return (\n          <Sequence from={i * 3}>\n            <AbsoluteFill>\n              <Move delay={0}>\n                <AbsoluteFill\n                  style={{\n                    scale: String(1 - i / amount),\n                  }}\n                >\n                  {children}\n                </AbsoluteFill>\n              </Move>\n            </AbsoluteFill>\n          </Sequence>\n        );\n      })}\n    </AbsoluteFill>\n  );\n};\n```\n\nIn your main component, you now replace the `<Move>` component with the `<Trail>` component:\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC<{}> = () => null;\n// @filename: Trail.tsx\nexport const Trail: React.FC<{\n  children: React.ReactNode;\n  amount: number;\n}> = () => null;\n\n// @filename: Composition.tsx\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dot} from './Dot';\nimport {Shrinking} from './Shrinking';\nimport {Trail} from './Trail';\n// ---cut---\n\nexport const MyComposition = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Trail amount={4}>\n        <Shrinking>\n          <Dot />\n        </Shrinking>\n      </Trail>\n    </AbsoluteFill>\n  );\n};\n```\n\nAnd this is how your animation with the duplicated dots should look like:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Trail.gif\" />\n\n## Duplicating markup and arranging it in a circle\n\nNow let's create a `<Explosion>` component. It takes children and renders them for example 10 times and applies a rotation to each instance. It's worth mentioning here that a full rotation amounts to 2π, while `(i/AMOUNT)` represents a factor between 0 and 1.\n\n```tsx twoslash title=\"src/Explosion.tsx\"\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\n\nconst AMOUNT = 10;\n\nexport const Explosion: React.FC<{\n  children: React.ReactNode;\n}> = ({children}) => {\n  return (\n    <AbsoluteFill>\n      {new Array(AMOUNT).fill(true).map((_, i) => {\n        return (\n          <AbsoluteFill\n            style={{\n              rotate: (i / AMOUNT) * (2 * Math.PI) + 'rad',\n            }}\n          >\n            {children}\n          </AbsoluteFill>\n        );\n      })}\n    </AbsoluteFill>\n  );\n};\n```\n\n`<Trail>` gets put inside the `<Explosion>` component. Your main component (`src/Composition.tsx`) looks like this:\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Explosion.tsx\nexport const Explosion: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC<{}> = () => null;\n// @filename: Trail.tsx\nexport const Trail: React.FC<{\n  children: React.ReactNode;\n  amount: number;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dot} from './Dot';\nimport {Explosion} from './Explosion';\nimport {Shrinking} from './Shrinking';\nimport {Trail} from './Trail';\n// ---cut---\n\nexport const MyComposition = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Explosion>\n        <Trail amount={4}>\n          <Shrinking>\n            <Dot />\n          </Shrinking>\n        </Trail>\n      </Explosion>\n    </AbsoluteFill>\n  );\n};\n```\n\nThe animated explosion should look like this:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Explosion.gif\" />\n\n## Cleanup\n\nYou have created a bunch of files until now, let's put most of them together in one file called `src/Dots.tsx`. Extract `<Explosion>` and it's children into a new separate component called Dots.\n\n```tsx twoslash title=\"src/Dots.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Explosion.tsx\nexport const Explosion: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC<{}> = () => null;\n// @filename: Trail.tsx\nexport const Trail: React.FC<{\n  children: React.ReactNode;\n  amount: number;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {Sequence} from 'remotion';\nimport {Dot} from './Dot';\nimport {Explosion} from './Explosion';\nimport {Shrinking} from './Shrinking';\nimport {Trail} from './Trail';\n\nexport const Dots: React.FC = () => {\n  return (\n    <Explosion>\n      <Trail amount={4}>\n        <Shrinking>\n          <Sequence from={5}>\n            <Dot />\n          </Sequence>\n        </Shrinking>\n      </Trail>\n    </Explosion>\n  );\n};\n```\n\nReplace the `<Explosion>` with the new `<Dots>` component:\n\n```tsx twoslash\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dots.tsx\nexport const Dots: React.FC<{}> = () => null;\n\n// @filename: MyComposition.tsx\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dots} from './Dots';\n// ---cut---\n\nexport const MyComposition = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Dots />\n    </AbsoluteFill>\n  );\n};\n```\n\nNothing has changed on the animation itself:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Dots.gif\" />\n\n## Adding hearts and stars\n\nTo make the animation more exciting, let's add some stars and hearts in different colors. To do this, we need to basically repeat the previous steps. Besides the `<Dots>`component, we'll add three more components in the next few steps.\n\nLet's start with red hearts. First you render a red heart by creating a new file `src/RedHeart.tsx` and return a centered red heart emoji.\n\n```tsx twoslash title=\"src/RedHeart.tsx\"\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\n\nexport const RedHeart: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        justifyContent: 'center',\n        alignItems: 'center',\n      }}\n    >\n      ❤️\n    </AbsoluteFill>\n  );\n};\n```\n\nEffects like `<Shrinking>`, `<Move>` and `<Explosion>` need to be applied to that red heart. We do this in a new component called RedHearts.\n\nConsider s that we need to add an offset to `<RedHearts>`, otherwise they would be positioned the same as the `<Dots>`.\n\nWe change the position by giving the red hearts a bigger radius than the dots, and apply a `100px` translation. Also, we add a short delay of 5 frames to the `<Move>` component:\n\n```tsx twoslash title=\"src/RedHearts.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Explosion.tsx\nexport const Explosion: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC<{}> = () => null;\n// @filename: RedHeart.tsx\nexport const RedHeart: React.FC<{}> = () => null;\n// @filename: Trail.tsx\nexport const Trail: React.FC<{\n  children: React.ReactNode;\n  extraOffset: number;\n  amount: number;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Explosion} from './Explosion';\nimport {Move} from './Move';\nimport {RedHeart} from './RedHeart';\nimport {Shrinking} from './Shrinking';\n\nexport const RedHearts: React.FC = () => {\n  return (\n    <Explosion>\n      <Move delay={5}>\n        <AbsoluteFill style={{transform: `translateY(-100px)`}}>\n          <Shrinking>\n            <RedHeart />\n          </Shrinking>\n        </AbsoluteFill>\n      </Move>\n    </Explosion>\n  );\n};\n```\n\nWe do the same to get some yellow hearts in our animation:\n\n```tsx twoslash title=\"src/YellowHeart.tsx\"\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\n\nexport const YellowHeart: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        justifyContent: 'center',\n        alignItems: 'center',\n      }}\n    >\n      💛\n    </AbsoluteFill>\n  );\n};\n```\n\nFor the yellow hearts we are going to change the position by applying a translation of `50px` and adding a delay of 20 frames to the `<Move>` component:\n\n```tsx twoslash title=\"src/YellowHearts.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Explosion.tsx\nexport const Explosion: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: YellowHeart.tsx\nexport const YellowHeart: React.FC<{}> = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC<{}> = () => null;\n// @filename: RedHeart.tsx\nexport const RedHeart: React.FC<{}> = () => null;\n// @filename: Trail.tsx\nexport const Trail: React.FC<{\n  children: React.ReactNode;\n  extraOffset: number;\n  amount: number;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Explosion} from './Explosion';\nimport {Move} from './Move';\nimport {Shrinking} from './Shrinking';\nimport {YellowHeart} from './YellowHeart';\n\nexport const YellowHearts: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        rotate: '0.3rad',\n      }}\n    >\n      <Explosion>\n        <Move delay={20}>\n          <AbsoluteFill\n            style={{\n              transform: `translateY(-50px)`,\n            }}\n          >\n            <Shrinking>\n              <YellowHeart />\n            </Shrinking>\n          </AbsoluteFill>\n        </Move>\n      </Explosion>\n    </AbsoluteFill>\n  );\n};\n```\n\nYour main composition should look like this:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/DotsAndHearts.gif\" />\n\n<br />\n<br />\n\nIn addition to the dots and hearts let's also add stars.\n\nCreate a new file `src/Star.tsx` and return a centered star emoji.\n\n```tsx twoslash title=\"src/Star.tsx\"\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\n\nexport const Star: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        justifyContent: 'center',\n        alignItems: 'center',\n        fontSize: 14,\n      }}\n    >\n      ⭐\n    </AbsoluteFill>\n  );\n};\n```\n\nConsider that we need to change the positioning of the stars, otherwise they would be on top of the `<Dots>`.\n\nLet's give `<Trail>` an `extraOffset` prop, so the stars can start more outwards than the dots.\n\nAn `extraOffset` of 100 for the stars leads to the same circumference at the beginning and end as the red hearts have. Here is the adjusted `<Trail>`:\n\n```tsx twoslash title=\"src/Trail.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n\n// @filename: Trail.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill, Sequence} from 'remotion';\nimport {Move} from './Move';\n\nexport const Trail: React.FC<{\n  amount: number;\n  extraOffset: number;\n  children: React.ReactNode;\n}> = ({amount, extraOffset, children}) => {\n  return (\n    <AbsoluteFill>\n      {new Array(amount).fill(true).map((a, i) => {\n        return (\n          <Sequence from={i * 3}>\n            <AbsoluteFill\n              style={{\n                translate: `0 ${-extraOffset}px`,\n              }}\n            >\n              <Move delay={0}>\n                <AbsoluteFill\n                  style={{\n                    scale: String(1 - i / amount),\n                  }}\n                >\n                  {children}\n                </AbsoluteFill>\n              </Move>\n            </AbsoluteFill>\n          </Sequence>\n        );\n      })}\n    </AbsoluteFill>\n  );\n};\n```\n\nEffects like `<Shrinking>`, the new `<Trail>` and `<Explosion>` need to be applied to the star we created above. Additionally we also add some rotation. We do all of this in a new component called Stars:\n\n```tsx twoslash title=\"src/Stars.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Explosion.tsx\nexport const Explosion: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dot.tsx\nexport const Dot: React.FC<{}> = () => null;\n// @filename: Star.tsx\nexport const Star: React.FC<{}> = () => null;\n// @filename: Trail.tsx\nexport const Trail: React.FC<{\n  children: React.ReactNode;\n  extraOffset: number;\n  amount: number;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Explosion} from './Explosion';\nimport {Shrinking} from './Shrinking';\nimport {Star} from './Star';\nimport {Trail} from './Trail';\n\nexport const Stars: React.FC = () => {\n  return (\n    <AbsoluteFill\n      style={{\n        rotate: '0.3rad',\n      }}\n    >\n      <Explosion>\n        <Trail extraOffset={100} amount={4}>\n          <Shrinking>\n            <Star />\n          </Shrinking>\n        </Trail>\n      </Explosion>\n    </AbsoluteFill>\n  );\n};\n```\n\nHere is how the almost complete firework should look like:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/DotsAndHeartsAndStars.gif\" />\n\n## Slow motion effect\n\nLastly let's apply a slow motion effect to the firework. For this, create a new file `src/SlowedTrail.tsx`. It should contain a component called Slowed and a helper function `remapSpeed()` which will apply different speed levels to the firework. In the code snippet below a speed of 1.5 is applied until frame 20, afterwards the speed slows down to 0.5.\n\n```tsx twoslash title=\"src/SlowedTrail.tsx\"\nimport React from 'react';\nimport {Freeze, interpolate, useCurrentFrame} from 'remotion';\n\n// remapSpeed() is a helper function for the component <Slowed> that takes a frame number and a speed\nconst remapSpeed = ({frame, speed}: {frame: number; speed: (fr: number) => number}) => {\n  let framesPassed = 0;\n  for (let i = 0; i <= frame; i++) {\n    framesPassed += speed(i);\n  }\n\n  return framesPassed;\n};\n\nexport const Slowed: React.FC<{\n  children: React.ReactNode;\n}> = ({children}) => {\n  const frame = useCurrentFrame();\n  const remappedFrame = remapSpeed({\n    frame,\n    speed: (f) =>\n      interpolate(f, [0, 20, 21], [1.5, 1.5, 0.5], {\n        extrapolateRight: 'clamp',\n      }),\n  });\n\n  return <Freeze frame={remappedFrame}>{children}</Freeze>;\n};\n```\n\nIn the main component, wrap all moving dots, hearts and stars in the component `<Slowed>`. As you sure can tell by now, everything is very composable:\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Stars.tsx\nexport const Stars: React.FC<{}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dots.tsx\nexport const Dots: React.FC<{}> = () => null;\n// @filename: RedHearts.tsx\nexport const RedHearts: React.FC<{}> = () => null;\n// @filename: YellowHearts.tsx\nexport const YellowHearts: React.FC<{}> = () => null;\n// @filename: SlowedTrail.tsx\nexport const Slowed: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Background} from './Background';\nimport {Dots} from './Dots';\nimport {RedHearts} from './RedHearts';\nimport {Slowed} from './SlowedTrail';\nimport {Stars} from './Stars';\nimport {YellowHearts} from './YellowHearts';\n\nexport const MyComposition = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Slowed>\n        <Dots />\n        <RedHearts />\n        <YellowHearts />\n        <Stars />\n      </Slowed>\n    </AbsoluteFill>\n  );\n};\n```\n\nYour final firework should look like this:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Slowed.gif\" />\n\n## Adding your animoji\n\nAs the final step of this tutorial, we add your animoji on top of the firework. For the animoji you need to have an iPhone and a Mac. This is how you get it: On your iPhone in iMessage, record an animoji of yourself and send it to a friend. After you've done that, it will also appear in the Messages app on your Mac. Download your animoji there by right-clicking. Once you have done that, create a transparent version of your animoji. Just follow these points:\n\n1. Right-click your downloaded animoji\n2. Select \"Services\"\n3. Select \"Encode Selected Video Files\"\n4. Choose \"Apple ProRes\" in the settings dropdown\n5. Tick the box that says \"Preserve Transparency\".\n\nA new encoded file of your animoji will be created. Give it a simple name like animoji.mov.\n\nIn addition to the `src` folder in your Remotion project, create a new one called `public`. Put your encoded video in this folder. You can then use FFmpeg to turn the encoded video into a series of frames:\n\n1. Change the current working directory to `public`: `cd public`\n2. Use this command: `ffmpeg -i animoji.mov -pix_fmt rgba -start_number 0 frame%03d.png`\n\nOnly assets that are being used by Remotion need to be in the `public` folder. You don't need the encoded video, so you can delete it after the frames have been extracted.\n\nHere is a screenshot right before creating the series of frames:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/FFmpegCommand.png\" />\n\n<br />\n<br />\n\nAlright, so far you've prepared the animoji to be used in a new component called Animoji. You can import this series of frames by using the [staticFile()](https://www.remotion.dev/docs/staticfile) API. The file name of each frame will help you to determine the current frame number.\n\n```tsx twoslash title=\"src/Animoji.tsx\"\nimport React from 'react';\nimport {AbsoluteFill, Img, staticFile, useCurrentFrame} from 'remotion';\n\nexport const Animoji: React.FC = () => {\n  const frame = useCurrentFrame();\n\n  const src = `frame${(frame * 2).toString().padStart(3, '0')}.png`;\n\n  return (\n    <AbsoluteFill\n      style={{\n        justifyContent: 'center',\n        alignItems: 'center',\n        marginTop: 80,\n      }}\n    >\n      <Img\n        style={{\n          height: 800,\n        }}\n        src={staticFile(src)}\n      />\n    </AbsoluteFill>\n  );\n};\n```\n\nRender the `<Animoji>` component in your main composition:\n\n```tsx twoslash title=\"src/Composition.tsx\"\n// @filename: Move.tsx\nexport const Move: React.FC<{\n  children: React.ReactNode;\n  delay: number;\n}> = () => null;\n// @filename: Shrinking.tsx\nexport const Shrinking: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n// @filename: Stars.tsx\nexport const Stars: React.FC<{}> = () => null;\n// @filename: Background.tsx\nexport const Background: React.FC<{}> = () => null;\n// @filename: Dots.tsx\nexport const Dots: React.FC<{}> = () => null;\n// @filename: RedHearts.tsx\nexport const RedHearts: React.FC<{}> = () => null;\n// @filename: YellowHearts.tsx\nexport const YellowHearts: React.FC<{}> = () => null;\n// @filename: Animoji.tsx\nexport const Animoji: React.FC<{}> = () => null;\n// @filename: SlowedTrail.tsx\nexport const Slowed: React.FC<{\n  children: React.ReactNode;\n}> = () => null;\n\n// @filename: MyComposition.tsx\n// ---cut---\nimport React from 'react';\nimport {AbsoluteFill} from 'remotion';\nimport {Animoji} from './Animoji';\nimport {Background} from './Background';\nimport {Dots} from './Dots';\nimport {RedHearts} from './RedHearts';\nimport {Slowed} from './SlowedTrail';\nimport {Stars} from './Stars';\nimport {YellowHearts} from './YellowHearts';\n\nexport const MyComposition = () => {\n  return (\n    <AbsoluteFill>\n      <Background />\n      <Slowed>\n        <Dots />\n        <RedHearts />\n        <YellowHearts />\n        <Stars />\n      </Slowed>\n      <Animoji />\n    </AbsoluteFill>\n  );\n};\n```\n\nBy doing all of this you have imported a transparent version of your animoji into your composition. You can run `npm run build` to export your video as MP4. Which should look like this:\n\n<img src=\"https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Final.gif\" />\n\nCongrats on your programmatically generated video! 🎉\n"</script>
<!-- -->
<p>Learn how to create an animation that Apple has on its website during the holiday season with this beginner-friendly Remotion tutorial!</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Final.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="video-version">Video version<a href="https://www.remotion.dev/learn/apple-wow#video-version" class="hash-link" aria-label="Direct link to Video version" title="Direct link to Video version" translate="no">​</a></h2>
<p>This tutorial is also available as a video version:</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="source-code">Source code<a href="https://www.remotion.dev/learn/apple-wow#source-code" class="hash-link" aria-label="Direct link to Source code" title="Direct link to Source code" translate="no">​</a></h2>
<p><a href="https://github.com/remotion-dev/apple-wow-tutorial" target="_blank" rel="noopener noreferrer" class="">GitHub</a></p>
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="getting-started">Getting started<a href="https://www.remotion.dev/learn/apple-wow#getting-started" class="hash-link" aria-label="Direct link to Getting started" title="Direct link to Getting started" translate="no">​</a></h2>
<p>Start a new Remotion project and select the blank template:</p>
<div class="theme-tabs-container tabs-container tabList_iv6T"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_wlVs tabs__item--active">npm</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_wlVs">yarn</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_wlVs">pnpm</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_osxV"><div><pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">npm</span><span style="color:#9ECBFF"> init</span><span style="color:#9ECBFF"> video</span><span style="color:#79B8FF"> --blank</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div></div><div role="tabpanel" class="tabItem_osxV" hidden=""><div><pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">pnpm</span><span style="color:#9ECBFF"> create</span><span style="color:#9ECBFF"> video</span><span style="color:#79B8FF"> --blank</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div></div><div role="tabpanel" class="tabItem_osxV" hidden=""><div><pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">yarn</span><span style="color:#9ECBFF"> create</span><span style="color:#9ECBFF"> video</span><span style="color:#79B8FF"> --blank</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="composition-setup">Composition setup<a href="https://www.remotion.dev/learn/apple-wow#composition-setup" class="hash-link" aria-label="Direct link to Composition setup" title="Direct link to Composition setup" translate="no">​</a></h2>
<p>A <a href="https://www.remotion.dev/docs/terminology/composition" target="_blank" rel="noopener noreferrer" class=""><code>&lt;Composition&gt;</code></a> defines the dimensions and duration of the video. In the <code>src/Root.tsx</code> file, adjust the width and height to the following:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Root.tsx</div><code><span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const RemotionRoot: React.FC<{}>">RemotionRoot</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
export namespace React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Composition: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(props: CompositionProps<Schema, Props>) => JSX.Element | null
import Composition">Composition</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) id: string">id</data-lsp></span><span style="color:#F97583">=</span><span style="color:#9ECBFF">"MyComp"</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) component: LooseComponentType<{}>">component</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#E1E4E8"><data-lsp lsp="const MyComposition: React.FC<{}>">MyComposition</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#B392F0"><data-lsp lsp="(property) durationInFrames: number">durationInFrames</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">150</span><span style="color:#E1E4E8">} </span><span style="color:#B392F0"><data-lsp lsp="(property) fps: number">fps</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">30</span><span style="color:#E1E4E8">} </span><span style="color:#B392F0"><data-lsp lsp="(property) width: number">width</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">1920</span><span style="color:#E1E4E8">} </span><span style="color:#B392F0"><data-lsp lsp="(property) height: number">height</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">1080</span><span style="color:#E1E4E8">} /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="create-a-background">Create a background<a href="https://www.remotion.dev/learn/apple-wow#create-a-background" class="hash-link" aria-label="Direct link to Create a background" title="Direct link to Create a background" translate="no">​</a></h2>
<p>Create a new file <code>src/Background.tsx</code> and return a background with linear gradient:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Background.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const Background: React.FC<{}>">Background</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardShorthandProperties<string | number, string &amp; {}>.background?: Property.Background<string | number> | undefined">background</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'linear-gradient(to bottom, #000021, #010024)'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Add the created background to the <code>&lt;MyComposition/&gt;</code> component, which can be found in the file <code>src/Composition.tsx</code>. This file will contain all the components that you create in this tutorial.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: React.FC<{}>">MyComposition</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>This results in the following:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Background.png">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="render-a-dot">Render a dot<a href="https://www.remotion.dev/learn/apple-wow#render-a-dot" class="hash-link" aria-label="Direct link to Render a dot" title="Direct link to Render a dot" translate="no">​</a></h2>
<p>Render a white dot by creating a new file <code>src/Dot.tsx</code> and return a centered circle.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Dot.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const Dot: React.FC<{}>">Dot</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.justifyContent?: Property.JustifyContent | undefined">justifyContent</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.alignItems?: Property.AlignItems | undefined">alignItems</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#85E89D"><data-lsp lsp="(property) React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>">div</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">        </span><span style="color:#B392F0"><data-lsp lsp="(property) React.HTMLAttributes<T>.style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">          </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.height?: Property.Height<string | number> | undefined">height</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">          </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.width?: Property.Width<string | number> | undefined">width</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">          </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardShorthandProperties<string | number, string &amp; {}>.borderRadius?: Property.BorderRadius<string | number> | undefined">borderRadius</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#F97583"> /</span><span style="color:#79B8FF"> 2</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">          </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.backgroundColor?: Property.BackgroundColor | undefined">backgroundColor</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'#ccc'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        }}</span></span>
<span class="line"><span style="color:#E1E4E8">      /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Add the <code>&lt;Dot&gt;</code> in your main composition <code>src/Composition.tsx</code>:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: React.FC<{}>">MyComposition</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Now we got a white dot on top of our background:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Dot.png">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="animate-the-dot">Animate the dot<a href="https://www.remotion.dev/learn/apple-wow#animate-the-dot" class="hash-link" aria-label="Direct link to Animate the dot" title="Direct link to Animate the dot" translate="no">​</a></h2>
<p>Let's apply some animation to the white dot we created above. We create another component called <code>&lt;Shrinking&gt;</code> in a new file <code>src/Shrinking.tsx</code>, which then wraps the dot in the main composition <code>src/Composition.tsx</code>.</p>
<div><pre class="shiki with-title github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Shrinking.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> React </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {AbsoluteFill, interpolate, useCurrentFrame} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> Shrinking</span><span style="color:#F97583">:</span><span style="color:#B392F0"> React</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">FC</span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  children</span><span style="color:#F97583">:</span><span style="color:#B392F0"> React</span><span style="color:#E1E4E8">.</span><span style="color:#B392F0">ReactNode</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70">children</span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> frame</span><span style="color:#F97583"> =</span><span style="color:#B392F0"> useCurrentFrame</span><span style="color:#E1E4E8">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF">AbsoluteFill</span></span>
<span class="line"><span style="color:#B392F0">      style</span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        scale: </span><span style="color:#B392F0">String</span><span style="color:#E1E4E8">(</span></span>
<span class="line"><span style="color:#B392F0">          interpolate</span><span style="color:#E1E4E8">(frame, [</span><span style="color:#79B8FF">60</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">90</span><span style="color:#E1E4E8">], [</span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">], {</span></span>
<span class="line"><span style="color:#E1E4E8">            extrapolateLeft: </span><span style="color:#9ECBFF">'clamp'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">            extrapolateRight: </span><span style="color:#9ECBFF">'clamp'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">          }),</span></span>
<span class="line"><span style="color:#E1E4E8">        ),</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      {children}</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF">AbsoluteFill</span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Add the <code>&lt;Shrinking&gt;</code> component in your main composition <code>src/Composition.tsx</code>:</p>
<div><pre class="shiki github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: React.FC<{}>">MyComposition</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Now, you have some action to show. By using <code>&lt;Shrinking&gt;</code> in your main composition you have created a scale out effect:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Shrinking.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="move-the-dot">Move the dot<a href="https://www.remotion.dev/learn/apple-wow#move-the-dot" class="hash-link" aria-label="Direct link to Move the dot" title="Direct link to Move the dot" translate="no">​</a></h2>
<p>Next, create a component called <code>&lt;Move&gt;</code>. This component has a spring animation, which by default goes from zero to one, and has a duration of four seconds (<code>durationInFrames: 120</code>) in the code snippet below:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Move.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) function interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number
import interpolate">interpolate</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) function spring({ frame: passedFrame, fps, config, from, to, durationInFrames: passedDurationInFrames, durationRestThreshold, delay, reverse }: {
    frame: number;
    fps: number;
    config?: Partial<SpringConfig>;
    from?: number;
    to?: number;
    durationInFrames?: number;
    durationRestThreshold?: number;
    delay?: number;
    reverse?: boolean;
}): number
import spring">spring</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const useCurrentFrame: () => number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const useVideoConfig: () => VideoConfig
import useVideoConfig">useVideoConfig</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const Move: React.FC<{
    children: React.ReactNode;
}>">Move</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) children: React.ReactNode">children</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<AwaitedReactNode> | null | undefined">ReactNode</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#E1E4E8"> {</span><span style="color:#79B8FF"><data-lsp lsp="const fps: number">fps</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">=</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) useVideoConfig(): VideoConfig
import useVideoConfig">useVideoConfig</data-lsp></span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const frame: number">frame</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) useCurrentFrame(): number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const down: number">down</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) spring({ frame: passedFrame, fps, config, from, to, durationInFrames: passedDurationInFrames, durationRestThreshold, delay, reverse }: {
    frame: number;
    fps: number;
    config?: Partial<SpringConfig>;
    from?: number;
    to?: number;
    durationInFrames?: number;
    durationRestThreshold?: number;
    delay?: number;
    reverse?: boolean;
}): number
import spring">spring</data-lsp></span><span style="color:#E1E4E8">({</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) fps: number">fps</data-lsp></span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) frame: number">frame</data-lsp></span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) config?: Partial<SpringConfig> | undefined">config</data-lsp></span><span style="color:#E1E4E8">: {</span></span>
<span class="line"><span style="color:#E1E4E8">      </span><span style="color:#E1E4E8"><data-lsp lsp="(property) damping?: number | undefined">damping</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">200</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">    },</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) durationInFrames?: number | undefined">durationInFrames</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">120</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const y: number">y</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number
import interpolate">interpolate</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="const down: number">down</data-lsp></span><span style="color:#E1E4E8">, [</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">], [</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#F97583">-</span><span style="color:#79B8FF">400</span><span style="color:#E1E4E8">]);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.translate?: Property.Translate<string | number> | undefined">translate</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">`0 ${</span><span style="color:#E1E4E8"><data-lsp lsp="const y: number">y</data-lsp></span><span style="color:#9ECBFF">}px`</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      {</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Add the <code>&lt;Move&gt;</code> component to your composition <code>src/Composition.tsx</code>. You get a nice animation by combining the effect of moving and shrinking by surrounding the shrinking dot in the <code>&lt;Move&gt;</code> component:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: () => JSX.Element">MyComposition</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>And up goes the dot:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Move.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="duplicate-the-moving-dot">Duplicate the moving dot<a href="https://www.remotion.dev/learn/apple-wow#duplicate-the-moving-dot" class="hash-link" aria-label="Direct link to Duplicate the moving dot" title="Direct link to Duplicate the moving dot" translate="no">​</a></h2>
<p>Here it gets a little bit trickier, but the following steps are going to make your animation a lot more entertaining. First, you add a <code>delay</code> prop into the <code>&lt;Move&gt;</code> component and then change the <code>frame</code> parameter of your <code>spring()</code> function.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Move.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) function interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number
import interpolate">interpolate</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) function spring({ frame: passedFrame, fps, config, from, to, durationInFrames: passedDurationInFrames, durationRestThreshold, delay, reverse }: {
    frame: number;
    fps: number;
    config?: Partial<SpringConfig>;
    from?: number;
    to?: number;
    durationInFrames?: number;
    durationRestThreshold?: number;
    delay?: number;
    reverse?: boolean;
}): number
import spring">spring</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const useCurrentFrame: () => number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const useVideoConfig: () => VideoConfig
import useVideoConfig">useVideoConfig</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>">Move</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) children: React.ReactNode">children</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<AwaitedReactNode> | null | undefined">ReactNode</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) delay: number">delay</data-lsp></span><span style="color:#F97583">:</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) delay: number">delay</data-lsp></span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#E1E4E8"> {</span><span style="color:#79B8FF"><data-lsp lsp="const fps: number">fps</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">=</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) useVideoConfig(): VideoConfig
import useVideoConfig">useVideoConfig</data-lsp></span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const frame: number">frame</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) useCurrentFrame(): number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const down: number">down</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) spring({ frame: passedFrame, fps, config, from, to, durationInFrames: passedDurationInFrames, durationRestThreshold, delay, reverse }: {
    frame: number;
    fps: number;
    config?: Partial<SpringConfig>;
    from?: number;
    to?: number;
    durationInFrames?: number;
    durationRestThreshold?: number;
    delay?: number;
    reverse?: boolean;
}): number
import spring">spring</data-lsp></span><span style="color:#E1E4E8">({</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) fps: number">fps</data-lsp></span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) frame: number">frame</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#E1E4E8"><data-lsp lsp="const frame: number">frame</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">-</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) delay: number">delay</data-lsp></span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) config?: Partial<SpringConfig> | undefined">config</data-lsp></span><span style="color:#E1E4E8">: {</span></span>
<span class="line"><span style="color:#E1E4E8">      </span><span style="color:#E1E4E8"><data-lsp lsp="(property) damping?: number | undefined">damping</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">200</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">    },</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) durationInFrames?: number | undefined">durationInFrames</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">120</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const y: number">y</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number
import interpolate">interpolate</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="const down: number">down</data-lsp></span><span style="color:#E1E4E8">, [</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">], [</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#F97583">-</span><span style="color:#79B8FF">400</span><span style="color:#E1E4E8">]);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.translate?: Property.Translate<string | number> | undefined">translate</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">`0 ${</span><span style="color:#E1E4E8"><data-lsp lsp="const y: number">y</data-lsp></span><span style="color:#9ECBFF">}px`</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      {</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Now, let's create a <code>&lt;Trail&gt;</code> component. It takes some React children and duplicates them. The component adds a delay to each subsequent dot so they don't start all at once. Each dot will have a scale applied to it, so that each dot is smaller than the previous one.</p>
<p>Put the previously created <code>&lt;Move&gt;</code> component within the <code>&lt;Trail&gt;</code> component.
The order is crucial here. Things are done from inside out:</p>
<ol>
<li class="">Apply a scale so that the dots become smaller over time.</li>
<li class="">Apply the move animation.</li>
<li class="">Apply a delay between the animation start of each dot by using Remotion's <code>&lt;Sequence&gt;</code> component.</li>
</ol>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Trail.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Move'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const Trail: React.FC<{
    amount: number;
    children: React.ReactNode;
}>">Trail</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) amount: number">amount</data-lsp></span><span style="color:#F97583">:</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) children: React.ReactNode">children</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<AwaitedReactNode> | null | undefined">ReactNode</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) amount: number">amount</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      {</span><span style="color:#F97583">new</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="var Array: ArrayConstructor
new (arrayLength?: number) => any[] (+2 overloads)">Array</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) amount: number">amount</data-lsp></span><span style="color:#E1E4E8">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Array<any>.fill(value: any, start?: number, end?: number): any[]">fill</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">true</span><span style="color:#E1E4E8">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Array<any>.map<JSX.Element>(callbackfn: (value: any, index: number, array: any[]) => JSX.Element, thisArg?: any): JSX.Element[]">map</data-lsp></span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) a: any">a</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">        return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) from?: number | undefined">from</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">*</span><span style="color:#79B8FF"> 3</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">              &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) delay: number">delay</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">                &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">                  </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">                    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.scale?: Property.Scale | undefined">scale</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#B392F0"><data-lsp lsp="var String: StringConstructor
(value?: any) => string">String</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">1</span><span style="color:#F97583"> -</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">/</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) amount: number">amount</data-lsp></span><span style="color:#E1E4E8">),</span></span>
<span class="line"><span style="color:#E1E4E8">                  }}</span></span>
<span class="line"><span style="color:#E1E4E8">                &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">                  {</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#E1E4E8">                &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">              &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        );</span></span>
<span class="line"><span style="color:#E1E4E8">      })}</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>In your main component, you now replace the <code>&lt;Move&gt;</code> component with the <code>&lt;Trail&gt;</code> component:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: () => JSX.Element">MyComposition</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) amount: number">amount</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">4</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>And this is how your animation with the duplicated dots should look like:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Trail.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="duplicating-markup-and-arranging-it-in-a-circle">Duplicating markup and arranging it in a circle<a href="https://www.remotion.dev/learn/apple-wow#duplicating-markup-and-arranging-it-in-a-circle" class="hash-link" aria-label="Direct link to Duplicating markup and arranging it in a circle" title="Direct link to Duplicating markup and arranging it in a circle" translate="no">​</a></h2>
<p>Now let's create a <code>&lt;Explosion&gt;</code> component. It takes children and renders them for example 10 times and applies a rotation to each instance. It's worth mentioning here that a full rotation amounts to 2π, while <code>(i/AMOUNT)</code> represents a factor between 0 and 1.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Explosion.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const AMOUNT: 10">AMOUNT</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#79B8FF"> 10</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const Explosion: React.FC<{
    children: React.ReactNode;
}>">Explosion</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) children: React.ReactNode">children</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<AwaitedReactNode> | null | undefined">ReactNode</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      {</span><span style="color:#F97583">new</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="var Array: ArrayConstructor
new (arrayLength?: number) => any[] (+2 overloads)">Array</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF"><data-lsp lsp="const AMOUNT: 10">AMOUNT</data-lsp></span><span style="color:#E1E4E8">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Array<any>.fill(value: any, start?: number, end?: number): any[]">fill</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">true</span><span style="color:#E1E4E8">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Array<any>.map<JSX.Element>(callbackfn: (value: any, index: number, array: any[]) => JSX.Element, thisArg?: any): JSX.Element[]">map</data-lsp></span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) _: any">_</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">        return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">            </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">              </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.rotate?: Property.Rotate | undefined">rotate</data-lsp></span><span style="color:#E1E4E8">: (</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">/</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const AMOUNT: 10">AMOUNT</data-lsp></span><span style="color:#E1E4E8">) </span><span style="color:#F97583">*</span><span style="color:#E1E4E8"> (</span><span style="color:#79B8FF">2</span><span style="color:#F97583"> *</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="var Math: Math">Math</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#79B8FF"><data-lsp lsp="(property) Math.PI: number">PI</data-lsp></span><span style="color:#E1E4E8">) </span><span style="color:#F97583">+</span><span style="color:#9ECBFF"> 'rad'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">            }}</span></span>
<span class="line"><span style="color:#E1E4E8">          &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            {</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        );</span></span>
<span class="line"><span style="color:#E1E4E8">      })}</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p><code>&lt;Trail&gt;</code> gets put inside the <code>&lt;Explosion&gt;</code> component. Your main component (<code>src/Composition.tsx</code>) looks like this:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: () => JSX.Element">MyComposition</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) amount: number">amount</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">4</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>The animated explosion should look like this:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Explosion.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="cleanup">Cleanup<a href="https://www.remotion.dev/learn/apple-wow#cleanup" class="hash-link" aria-label="Direct link to Cleanup" title="Direct link to Cleanup" translate="no">​</a></h2>
<p>You have created a bunch of files until now, let's put most of them together in one file called <code>src/Dots.tsx</code>. Extract <code>&lt;Explosion&gt;</code> and it's children into a new separate component called Dots.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Dots.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Dot'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Explosion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Shrinking'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Trail'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const Dots: React.FC<{}>">Dots</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) amount: number">amount</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">4</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) from?: number | undefined">from</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">5</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dot: React.FC<{}>
import Dot">Dot</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Replace the <code>&lt;Explosion&gt;</code> with the new <code>&lt;Dots&gt;</code> component:</p>
<div><pre class="shiki github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: () => JSX.Element">MyComposition</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dots: React.FC<{}>
import Dots">Dots</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Nothing has changed on the animation itself:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Dots.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="adding-hearts-and-stars">Adding hearts and stars<a href="https://www.remotion.dev/learn/apple-wow#adding-hearts-and-stars" class="hash-link" aria-label="Direct link to Adding hearts and stars" title="Direct link to Adding hearts and stars" translate="no">​</a></h2>
<p>To make the animation more exciting, let's add some stars and hearts in different colors. To do this, we need to basically repeat the previous steps. Besides the <code>&lt;Dots&gt;</code>component, we'll add three more components in the next few steps.</p>
<p>Let's start with red hearts. First you render a red heart by creating a new file <code>src/RedHeart.tsx</code> and return a centered red heart emoji.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/RedHeart.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const RedHeart: React.FC<{}>">RedHeart</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.justifyContent?: Property.JustifyContent | undefined">justifyContent</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.alignItems?: Property.AlignItems | undefined">alignItems</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      ❤️</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Effects like <code>&lt;Shrinking&gt;</code>, <code>&lt;Move&gt;</code> and <code>&lt;Explosion&gt;</code> need to be applied to that red heart. We do this in a new component called RedHearts.</p>
<p>Consider s that we need to add an offset to <code>&lt;RedHearts&gt;</code>, otherwise they would be positioned the same as the <code>&lt;Dots&gt;</code>.</p>
<p>We change the position by giving the red hearts a bigger radius than the dots, and apply a <code>100px</code> translation. Also, we add a short delay of 5 frames to the <code>&lt;Move&gt;</code> component:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/RedHearts.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Explosion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Move'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const RedHeart: React.FC<{}>
import RedHeart">RedHeart</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './RedHeart'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Shrinking'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const RedHearts: React.FC<{}>">RedHearts</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) delay: number">delay</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">5</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.transform?: Property.Transform | undefined">transform</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">`translateY(-100px)`</span><span style="color:#E1E4E8">}}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const RedHeart: React.FC<{}>
import RedHeart">RedHeart</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>We do the same to get some yellow hearts in our animation:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/YellowHeart.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const YellowHeart: React.FC<{}>">YellowHeart</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.justifyContent?: Property.JustifyContent | undefined">justifyContent</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.alignItems?: Property.AlignItems | undefined">alignItems</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      💛</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>For the yellow hearts we are going to change the position by applying a translation of <code>50px</code> and adding a delay of 20 frames to the <code>&lt;Move&gt;</code> component:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/YellowHearts.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Explosion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Move'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Shrinking'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const YellowHeart: React.FC<{}>
import YellowHeart">YellowHeart</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './YellowHeart'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const YellowHearts: React.FC<{}>">YellowHearts</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.rotate?: Property.Rotate | undefined">rotate</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'0.3rad'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) delay: number">delay</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">20</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">            </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">              </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.transform?: Property.Transform | undefined">transform</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">`translateY(-50px)`</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">            }}</span></span>
<span class="line"><span style="color:#E1E4E8">          &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">              &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const YellowHeart: React.FC<{}>
import YellowHeart">YellowHeart</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Your main composition should look like this:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/DotsAndHearts.gif">
<br>
<br>
<p>In addition to the dots and hearts let's also add stars.</p>
<p>Create a new file <code>src/Star.tsx</code> and return a centered star emoji.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Star.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const Star: React.FC<{}>">Star</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.justifyContent?: Property.JustifyContent | undefined">justifyContent</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.alignItems?: Property.AlignItems | undefined">alignItems</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.fontSize?: Property.FontSize<string | number> | undefined">fontSize</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">14</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      ⭐</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Consider that we need to change the positioning of the stars, otherwise they would be on top of the <code>&lt;Dots&gt;</code>.</p>
<p>Let's give <code>&lt;Trail&gt;</code> an <code>extraOffset</code> prop, so the stars can start more outwards than the dots.</p>
<p>An <code>extraOffset</code> of 100 for the stars leads to the same circumference at the beginning and end as the red hearts have. Here is the adjusted <code>&lt;Trail&gt;</code>:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Trail.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Move'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const Trail: React.FC<{
    amount: number;
    extraOffset: number;
    children: React.ReactNode;
}>">Trail</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) amount: number">amount</data-lsp></span><span style="color:#F97583">:</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) extraOffset: number">extraOffset</data-lsp></span><span style="color:#F97583">:</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) children: React.ReactNode">children</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<AwaitedReactNode> | null | undefined">ReactNode</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) amount: number">amount</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) extraOffset: number">extraOffset</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      {</span><span style="color:#F97583">new</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="var Array: ArrayConstructor
new (arrayLength?: number) => any[] (+2 overloads)">Array</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) amount: number">amount</data-lsp></span><span style="color:#E1E4E8">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Array<any>.fill(value: any, start?: number, end?: number): any[]">fill</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">true</span><span style="color:#E1E4E8">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Array<any>.map<JSX.Element>(callbackfn: (value: any, index: number, array: any[]) => JSX.Element, thisArg?: any): JSX.Element[]">map</data-lsp></span><span style="color:#E1E4E8">((</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) a: any">a</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">        return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) from?: number | undefined">from</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">*</span><span style="color:#79B8FF"> 3</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">              </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">                </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.translate?: Property.Translate<string | number> | undefined">translate</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">`0 ${</span><span style="color:#F97583">-</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) extraOffset: number">extraOffset</data-lsp></span><span style="color:#9ECBFF">}px`</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">              }}</span></span>
<span class="line"><span style="color:#E1E4E8">            &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">              &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) delay: number">delay</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">                &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">                  </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">                    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.scale?: Property.Scale | undefined">scale</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#B392F0"><data-lsp lsp="var String: StringConstructor
(value?: any) => string">String</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#79B8FF">1</span><span style="color:#F97583"> -</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">/</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) amount: number">amount</data-lsp></span><span style="color:#E1E4E8">),</span></span>
<span class="line"><span style="color:#E1E4E8">                  }}</span></span>
<span class="line"><span style="color:#E1E4E8">                &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">                  {</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#E1E4E8">                &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">              &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Move: React.FC<{
    children: React.ReactNode;
    delay: number;
}>
import Move">Move</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Sequence: React.ForwardRefExoticComponent<SequenceProps &amp; React.RefAttributes<HTMLDivElement>>
import Sequence">Sequence</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        );</span></span>
<span class="line"><span style="color:#E1E4E8">      })}</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Effects like <code>&lt;Shrinking&gt;</code>, the new <code>&lt;Trail&gt;</code> and <code>&lt;Explosion&gt;</code> need to be applied to the star we created above. Additionally we also add some rotation. We do all of this in a new component called Stars:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Stars.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Explosion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Shrinking'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Star: React.FC<{}>
import Star">Star</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Star'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    extraOffset: number;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Trail'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const Stars: React.FC<{}>">Stars</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.rotate?: Property.Rotate | undefined">rotate</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'0.3rad'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    extraOffset: number;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) extraOffset: number">extraOffset</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">100</span><span style="color:#E1E4E8">} </span><span style="color:#B392F0"><data-lsp lsp="(property) amount: number">amount</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#79B8FF">4</span><span style="color:#E1E4E8">}&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">            &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Star: React.FC<{}>
import Star">Star</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">          &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Shrinking: React.FC<{
    children: React.ReactNode;
}>
import Shrinking">Shrinking</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Trail: React.FC<{
    children: React.ReactNode;
    extraOffset: number;
    amount: number;
}>
import Trail">Trail</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Explosion: React.FC<{
    children: React.ReactNode;
}>
import Explosion">Explosion</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Here is how the almost complete firework should look like:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/DotsAndHeartsAndStars.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="slow-motion-effect">Slow motion effect<a href="https://www.remotion.dev/learn/apple-wow#slow-motion-effect" class="hash-link" aria-label="Direct link to Slow motion effect" title="Direct link to Slow motion effect" translate="no">​</a></h2>
<p>Lastly let's apply a slow motion effect to the firework. For this, create a new file <code>src/SlowedTrail.tsx</code>. It should contain a component called Slowed and a helper function <code>remapSpeed()</code> which will apply different speed levels to the firework. In the code snippet below a speed of 1.5 is applied until frame 20, afterwards the speed slows down to 0.5.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/SlowedTrail.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Freeze: React.FC<FreezeProps>
import Freeze">Freeze</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) function interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number
import interpolate">interpolate</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const useCurrentFrame: () => number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// remapSpeed() is a helper function for the component &lt;Slowed&gt; that takes a frame number and a speed</span></span>
<span class="line"><span style="color:#F97583">const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const remapSpeed: ({ frame, speed }: {
    frame: number;
    speed: (fr: number) => number;
}) => number">remapSpeed</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) frame: number">frame</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#FFAB70"><data-lsp lsp="(parameter) speed: (fr: number) => number">speed</data-lsp></span><span style="color:#E1E4E8">}</span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> {</span><span style="color:#FFAB70"><data-lsp lsp="(property) frame: number">frame</data-lsp></span><span style="color:#F97583">:</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">; </span><span style="color:#B392F0"><data-lsp lsp="(property) speed: (fr: number) => number">speed</data-lsp></span><span style="color:#F97583">:</span><span style="color:#E1E4E8"> (</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) fr: number">fr</data-lsp></span><span style="color:#F97583">:</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span><span style="color:#79B8FF"> number</span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  let</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="let framesPassed: number">framesPassed</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 0</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">  for</span><span style="color:#E1E4E8"> (</span><span style="color:#F97583">let</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="let i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 0</span><span style="color:#E1E4E8">; </span><span style="color:#E1E4E8"><data-lsp lsp="let i: number">i</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">&lt;=</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) frame: number">frame</data-lsp></span><span style="color:#E1E4E8">; </span><span style="color:#E1E4E8"><data-lsp lsp="let i: number">i</data-lsp></span><span style="color:#F97583">++</span><span style="color:#E1E4E8">) {</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="let framesPassed: number">framesPassed</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">+=</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(parameter) speed: (fr: number) => number">speed</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="let i: number">i</data-lsp></span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8">  }</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="let framesPassed: number">framesPassed</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const Slowed: React.FC<{
    children: React.ReactNode;
}>">Slowed</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#E1E4E8">&lt;{</span></span>
<span class="line"><span style="color:#FFAB70">  </span><span style="color:#FFAB70"><data-lsp lsp="(property) children: React.ReactNode">children</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.ReactNode = string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<AwaitedReactNode> | null | undefined">ReactNode</data-lsp></span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">}&gt; </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> ({</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}) </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const frame: number">frame</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) useCurrentFrame(): number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const remappedFrame: number">remappedFrame</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const remapSpeed: ({ frame, speed }: {
    frame: number;
    speed: (fr: number) => number;
}) => number">remapSpeed</data-lsp></span><span style="color:#E1E4E8">({</span></span>
<span class="line"><span style="color:#E1E4E8">    </span><span style="color:#E1E4E8"><data-lsp lsp="(property) frame: number">frame</data-lsp></span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#B392F0">    </span><span style="color:#B392F0"><data-lsp lsp="(property) speed: (fr: number) => number">speed</data-lsp></span><span style="color:#E1E4E8">: (</span><span style="color:#FFAB70"><data-lsp lsp="(parameter) f: number">f</data-lsp></span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=&gt;</span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(alias) interpolate(input: number, inputRange: readonly number[], outputRange: readonly number[], options?: InterpolateOptions): number
import interpolate">interpolate</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) f: number">f</data-lsp></span><span style="color:#E1E4E8">, [</span><span style="color:#79B8FF">0</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">20</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">21</span><span style="color:#E1E4E8">], [</span><span style="color:#79B8FF">1.5</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">1.5</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">0.5</span><span style="color:#E1E4E8">], {</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) extrapolateRight?: ExtrapolateType | undefined">extrapolateRight</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'clamp'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }),</span></span>
<span class="line"><span style="color:#E1E4E8">  });</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Freeze: React.FC<FreezeProps>
import Freeze">Freeze</data-lsp></span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(property) frame: number">frame</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#E1E4E8"><data-lsp lsp="const remappedFrame: number">remappedFrame</data-lsp></span><span style="color:#E1E4E8">}&gt;{</span><span style="color:#E1E4E8"><data-lsp lsp="(parameter) children: React.ReactNode">children</data-lsp></span><span style="color:#E1E4E8">}&lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Freeze: React.FC<FreezeProps>
import Freeze">Freeze</data-lsp></span><span style="color:#E1E4E8">&gt;;</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>In the main component, wrap all moving dots, hearts and stars in the component <code>&lt;Slowed&gt;</code>. As you sure can tell by now, everything is very composable:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Background'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Dots: React.FC<{}>
import Dots">Dots</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Dots'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const RedHearts: React.FC<{}>
import RedHearts">RedHearts</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './RedHearts'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Slowed: React.FC<{
    children: React.ReactNode;
}>
import Slowed">Slowed</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './SlowedTrail'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Stars: React.FC<{}>
import Stars">Stars</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Stars'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const YellowHearts: React.FC<{}>
import YellowHearts">YellowHearts</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './YellowHearts'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: () => JSX.Element">MyComposition</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Slowed: React.FC<{
    children: React.ReactNode;
}>
import Slowed">Slowed</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dots: React.FC<{}>
import Dots">Dots</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const RedHearts: React.FC<{}>
import RedHearts">RedHearts</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const YellowHearts: React.FC<{}>
import YellowHearts">YellowHearts</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Stars: React.FC<{}>
import Stars">Stars</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Slowed: React.FC<{
    children: React.ReactNode;
}>
import Slowed">Slowed</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Your final firework should look like this:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Slowed.gif">
<h2 class="anchor anchorTargetStickyNavbar_zrKg" id="adding-your-animoji">Adding your animoji<a href="https://www.remotion.dev/learn/apple-wow#adding-your-animoji" class="hash-link" aria-label="Direct link to Adding your animoji" title="Direct link to Adding your animoji" translate="no">​</a></h2>
<p>As the final step of this tutorial, we add your animoji on top of the firework. For the animoji you need to have an iPhone and a Mac. This is how you get it: On your iPhone in iMessage, record an animoji of yourself and send it to a friend. After you've done that, it will also appear in the Messages app on your Mac. Download your animoji there by right-clicking. Once you have done that, create a transparent version of your animoji. Just follow these points:</p>
<ol>
<li class="">Right-click your downloaded animoji</li>
<li class="">Select "Services"</li>
<li class="">Select "Encode Selected Video Files"</li>
<li class="">Choose "Apple ProRes" in the settings dropdown</li>
<li class="">Tick the box that says "Preserve Transparency".</li>
</ol>
<p>A new encoded file of your animoji will be created. Give it a simple name like animoji.mov.</p>
<p>In addition to the <code>src</code> folder in your Remotion project, create a new one called <code>public</code>. Put your encoded video in this folder. You can then use FFmpeg to turn the encoded video into a series of frames:</p>
<ol>
<li class="">Change the current working directory to <code>public</code>: <code>cd public</code></li>
<li class="">Use this command: <code>ffmpeg -i animoji.mov -pix_fmt rgba -start_number 0 frame%03d.png</code></li>
</ol>
<p>Only assets that are being used by Remotion need to be in the <code>public</code> folder. You don't need the encoded video, so you can delete it after the frames have been extracted.</p>
<p>Here is a screenshot right before creating the series of frames:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/FFmpegCommand.png">
<br>
<br>
<p>Alright, so far you've prepared the animoji to be used in a new component called Animoji. You can import this series of frames by using the <a href="https://www.remotion.dev/docs/staticfile" target="_blank" rel="noopener noreferrer" class="">staticFile()</a> API. The file name of each frame will help you to determine the current frame number.</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Animoji.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Img: React.ForwardRefExoticComponent<Omit<ImgProps, &quot;ref&quot;> &amp; React.RefAttributes<HTMLImageElement>>
import Img">Img</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const staticFile: (path: string) => string
import staticFile">staticFile</data-lsp></span><span style="color:#E1E4E8">, </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const useCurrentFrame: () => number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const Animoji: React.FC<{}>">Animoji</data-lsp></span><span style="color:#F97583">:</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8">.</span><span style="color:#B392F0"><data-lsp lsp="type React.FC<P = {}> = React.FunctionComponent<P>">FC</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const frame: number">frame</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="(alias) useCurrentFrame(): number
import useCurrentFrame">useCurrentFrame</data-lsp></span><span style="color:#E1E4E8">();</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  const</span><span style="color:#79B8FF"> </span><span style="color:#79B8FF"><data-lsp lsp="const src: string">src</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#9ECBFF"> `frame${</span><span style="color:#9ECBFF">(</span><span style="color:#E1E4E8"><data-lsp lsp="const frame: number">frame</data-lsp></span><span style="color:#F97583"> *</span><span style="color:#79B8FF"> 2</span><span style="color:#9ECBFF">).</span><span style="color:#B392F0"><data-lsp lsp="(method) Number.toString(radix?: number): string">toString</data-lsp></span><span style="color:#9ECBFF">().</span><span style="color:#B392F0"><data-lsp lsp="(method) String.padStart(maxLength: number, fillString?: string): string">padStart</data-lsp></span><span style="color:#9ECBFF">(</span><span style="color:#79B8FF">3</span><span style="color:#9ECBFF">, </span><span style="color:#9ECBFF">'0'</span><span style="color:#9ECBFF">)</span><span style="color:#9ECBFF">}.png`</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">      </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.justifyContent?: Property.JustifyContent | undefined">justifyContent</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.alignItems?: Property.AlignItems | undefined">alignItems</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">'center'</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.marginTop?: Property.MarginTop<string | number> | undefined">marginTop</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">80</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">      }}</span></span>
<span class="line"><span style="color:#E1E4E8">    &gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Img: React.ForwardRefExoticComponent<Omit<ImgProps, &quot;ref&quot;> &amp; React.RefAttributes<HTMLImageElement>>
import Img">Img</data-lsp></span></span>
<span class="line"><span style="color:#B392F0">        </span><span style="color:#B392F0"><data-lsp lsp="(property) style?: React.CSSProperties | undefined">style</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{{</span></span>
<span class="line"><span style="color:#E1E4E8">          </span><span style="color:#E1E4E8"><data-lsp lsp="(property) StandardLonghandProperties<string | number, string &amp; {}>.height?: Property.Height<string | number> | undefined">height</data-lsp></span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">800</span><span style="color:#E1E4E8">,</span></span>
<span class="line"><span style="color:#E1E4E8">        }}</span></span>
<span class="line"><span style="color:#B392F0">        </span><span style="color:#B392F0"><data-lsp lsp="(property) src: string">src</data-lsp></span><span style="color:#F97583">=</span><span style="color:#E1E4E8">{</span><span style="color:#B392F0"><data-lsp lsp="(alias) staticFile(path: string): string
import staticFile">staticFile</data-lsp></span><span style="color:#E1E4E8">(</span><span style="color:#E1E4E8"><data-lsp lsp="const src: string">src</data-lsp></span><span style="color:#E1E4E8">)}</span></span>
<span class="line"><span style="color:#E1E4E8">      /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>Render the <code>&lt;Animoji&gt;</code> component in your main composition:</p>
<div><pre class="shiki with-title github-dark twoslash lsp" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><div class="code-title">src/Composition.tsx</div><code><span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> </span><span style="color:#E1E4E8"><data-lsp lsp="(alias) namespace React
import React">React</data-lsp></span><span style="color:#E1E4E8"> </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'react'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> 'remotion'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Animoji: React.FC<{}>
import Animoji">Animoji</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Animoji'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Background'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Dots: React.FC<{}>
import Dots">Dots</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Dots'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const RedHearts: React.FC<{}>
import RedHearts">RedHearts</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './RedHearts'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Slowed: React.FC<{
    children: React.ReactNode;
}>
import Slowed">Slowed</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './SlowedTrail'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const Stars: React.FC<{}>
import Stars">Stars</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './Stars'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583">import</span><span style="color:#E1E4E8"> {</span><span style="color:#E1E4E8"><data-lsp lsp="(alias) const YellowHearts: React.FC<{}>
import YellowHearts">YellowHearts</data-lsp></span><span style="color:#E1E4E8">} </span><span style="color:#F97583">from</span><span style="color:#9ECBFF"> './YellowHearts'</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#F97583">export</span><span style="color:#F97583"> const</span><span style="color:#B392F0"> </span><span style="color:#B392F0"><data-lsp lsp="const MyComposition: () => JSX.Element">MyComposition</data-lsp></span><span style="color:#F97583"> =</span><span style="color:#E1E4E8"> () </span><span style="color:#F97583">=&gt;</span><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583">  return</span><span style="color:#E1E4E8"> (</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Background: React.FC<{}>
import Background">Background</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Slowed: React.FC<{
    children: React.ReactNode;
}>
import Slowed">Slowed</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Dots: React.FC<{}>
import Dots">Dots</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const RedHearts: React.FC<{}>
import RedHearts">RedHearts</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const YellowHearts: React.FC<{}>
import YellowHearts">YellowHearts</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">        &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Stars: React.FC<{}>
import Stars">Stars</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Slowed: React.FC<{
    children: React.ReactNode;
}>
import Slowed">Slowed</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">      &lt;</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const Animoji: React.FC<{}>
import Animoji">Animoji</data-lsp></span><span style="color:#E1E4E8"> /&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">    &lt;/</span><span style="color:#79B8FF"><data-lsp lsp="(alias) const AbsoluteFill: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, &quot;ref&quot;> &amp; React.RefAttributes<HTMLDivElement>>
import AbsoluteFill">AbsoluteFill</data-lsp></span><span style="color:#E1E4E8">&gt;</span></span>
<span class="line"><span style="color:#E1E4E8">  );</span></span>
<span class="line"><span style="color:#E1E4E8">};</span></span></code><button class="copy-button" aria-label="Copy code to clipboard">Copy</button></pre></div>
<p>By doing all of this you have imported a transparent version of your animoji into your composition. You can run <code>npm run build</code> to export your video as MP4. Which should look like this:</p>
<img src="https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/Final.gif">
<p>Congrats on your programmatically generated video! 🎉</p>]]></content:encoded>
        </item>
    </channel>
</rss>