Skip to content

Commit

Permalink
Merge pull request #1392 from codechem/feature/motion-blur
Browse files Browse the repository at this point in the history
  • Loading branch information
JonnyBurger committed Oct 13, 2022
2 parents 3465572 + 1158596 commit 020684b
Show file tree
Hide file tree
Showing 19 changed files with 556 additions and 10 deletions.
1 change: 1 addition & 0 deletions packages/cli/src/list-of-remotion-packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const listOfRemotionPackages = [
'@remotion/skia',
'@remotion/lottie',
'@remotion/media-utils',
'@remotion/motion-blur',
'@remotion/paths',
'@remotion/babel-loader',
'@remotion/lambda',
Expand Down
1 change: 1 addition & 0 deletions packages/create-video/src/patch-package-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const listOfRemotionPackages = [
'@remotion/skia',
'@remotion/lottie',
'@remotion/media-utils',
'@remotion/motion-blur',
'@remotion/paths',
'@remotion/babel-loader',
'@remotion/lambda',
Expand Down
192 changes: 192 additions & 0 deletions packages/docs/components/MotionBlurExample/MotionBlurExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import { Player } from "@remotion/player";
import React, { useState } from "react";
import {
AbsoluteFill,
Freeze,
interpolate,
spring,
useCurrentFrame,
useVideoConfig,
} from "remotion";

import { MotionBlur } from "@remotion/motion-blur";

const square: React.CSSProperties = {
height: 150,
width: 150,
backgroundColor: "#0b84f3",
borderRadius: 14,
};

const row: React.CSSProperties = {
display: "flex",
flexDirection: "row",
alignItems: "center",
};

const spacer: React.CSSProperties = {
width: 40,
};

export const Square: React.FC = () => {
const frame = useCurrentFrame();
const { fps, height } = useVideoConfig();
const spr = spring({
fps,
frame,
config: {
damping: 200,
},
durationInFrames: 60,
});

const rotate = interpolate(spr, [0, 1], [Math.PI, 0]);
const y = interpolate(spr, [0, 1], [height, 0]);

return (
<AbsoluteFill
style={{
justifyContent: "center",
alignItems: "center",
transform: `translateY(${y}px) rotate(${rotate}rad)`,
}}
>
<div style={square} />
</AbsoluteFill>
);
};

const MyComposition = ({
blurOpacity,
layers,
lagInFrames,
}: {
blurOpacity: number;
layers: number;
lagInFrames: number;
}) => {
return (
<AbsoluteFill
style={{
flexDirection: "row",
}}
>
<div style={{ flex: 1, position: "relative" }}>
<AbsoluteFill style={{ padding: 30 }}>
<h1>Still</h1>
</AbsoluteFill>
<Freeze frame={38}>
<MotionBlur
blurOpacity={blurOpacity}
lagInFrames={lagInFrames}
layers={layers}
>
<Square />
</MotionBlur>
</Freeze>
</div>
<div
style={{
width: 1,
background: "var(--ifm-color-emphasis-300)",
}}
/>
<div style={{ flex: 1, position: "relative" }}>
<AbsoluteFill style={{ padding: 30 }}>
<h1>Animation</h1>
</AbsoluteFill>
<MotionBlur
blurOpacity={blurOpacity}
lagInFrames={lagInFrames}
layers={layers}
>
<Square />
</MotionBlur>
</div>
</AbsoluteFill>
);
};

export const MotionBlurExample: React.FC = () => {
const [blurOpacity, setBlurOpacity] = useState(1);
const [lagInFrames, setFrameDelay] = useState(0.3);
const [layers, setLayers] = useState(50);

return (
<div>
<Player
component={MyComposition}
compositionWidth={1280}
compositionHeight={720}
durationInFrames={70}
fps={30}
style={{
width: "100%",
border: "1px solid var(--ifm-color-emphasis-300)",
borderRadius: "var(--ifm-pre-border-radius)",
}}
inputProps={{
blurOpacity,
lagInFrames,
layers,
}}
autoPlay
loop
/>
<br />
<div style={{ ...row, fontSize: 20 }}>
<label style={row}>
<input
type="range"
min={0}
max={100}
value={layers}
style={{ width: 90, marginRight: 8, padding: 8 }}
onChange={(e) => setLayers(Number(e.target.value))}
/>
<code>
layers={"{"}
{layers}
{"}"}
</code>
</label>
<div style={spacer} />

<label style={row}>
<input
type="range"
min={0}
max={1}
step={0.05}
value={blurOpacity}
style={{ width: 90, marginRight: 8 }}
onChange={(e) => setBlurOpacity(Number(e.target.value))}
/>
<code>
blurOpacity={"{"}
{blurOpacity}
{"}"}
</code>
</label>
<div style={spacer} />

<label style={row}>
<input
type="range"
min={0}
max={2}
step={0.1}
value={lagInFrames}
style={{ width: 90, marginRight: 8, padding: 8 }}
onChange={(e) => setFrameDelay(Number(e.target.value))}
/>
<code>
lagInFrames={"{"}
{lagInFrames}
{"}"}
</code>
</label>
</div>
</div>
);
};
16 changes: 16 additions & 0 deletions packages/docs/components/TableOfContents/motion-blur.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react";
import { Grid } from "./Grid";
import { TOCItem } from "./TOCItem";

export const TableOfContents: React.FC = () => {
return (
<div>
<Grid>
<TOCItem link="/docs/motion-blur/motion-blur">
<strong>{"<MotionBlur>"}</strong>
<div>Add a motion blur effect to children</div>
</TOCItem>
</Grid>
</div>
);
};
49 changes: 49 additions & 0 deletions packages/docs/docs/motion-blur/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: "@remotion/motion-blur"
---

_Available from v3.2.31_

A high order component that creates a motion blur effect.

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<Tabs
defaultValue="npm"
values={[
{ label: 'npm', value: 'npm', },
{ label: 'pnpm', value: 'pnpm', },
{ label: 'yarn', value: 'yarn', },
]
}>
<TabItem value="npm">

```bash
npm i @remotion/motion-blur
```

</TabItem>

<TabItem value="pnpm">

```bash
pnpm i @remotion/motion-blur
```

</TabItem>

<TabItem value="yarn">

```bash
yarn add @remotion/motion-blur
```

</TabItem>
</Tabs>

## Components

## License

MIT
75 changes: 75 additions & 0 deletions packages/docs/docs/motion-blur/motion-blur.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: "<MotionBlur>"
slug: motion-blur
---

import { MotionBlurExample } from "../../components/MotionBlurExample/MotionBlurExample";

import {TableOfContents} from '../../components/TableOfContents/motion-blur';

```twoslash include example
const BlueSquare: React.FC = () => <div></div>
// - BlueSquare
```

The `<MotionBlur>` component duplicates it's children and adds a time offset to each layer in order to create a motion blur effect.

For this technique to work, the children must be absolutely positioned so many layers can be created without influencing the layout.
You can use the [`<AbsoluteFill>`](/docs/absolute-fill) component to absolutely position content.

## API

Wrap your content in `<MotionBlur>` and add the following props in addition.

### `layers`

How many layers are added below the content. Must be an integer

### `lagInFrames`

How many frames each layer is lagging behind the last one. Can also a floating point number.

### `blurOpacity`

The highest opacity of a layer. The lowest opacity is 0 and layers intbetween get interpolated.

## Example usage

```tsx twoslash
// @include: example-BlueSquare
// ---cut---
import { MotionBlur } from "@remotion/motion-blur";
import { AbsoluteFill } from "remotion";

export const MyComposition = () => {
return (
<MotionBlur layers={50} lagInFrames={0.1} blurOpacity={1}>
<AbsoluteFill
style={{
backgroundColor: "white",
justifyContent: "center",
alignItems: "center",
}}
>
<BlueSquare />
</AbsoluteFill>
</MotionBlur>
);
};
```

## Demo

<MotionBlurExample />

## Functions

<TableOfContents />

## Credits

This technique was invented and first implemented by [@UmungoBungo](https://github.com/UmungoBungo).

## See also

- [Source code for this component](https://github.com/remotion-dev/remotion/blob/main/packages/motion-blur/src/MotionBlur.tsx)
1 change: 1 addition & 0 deletions packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@remotion/lambda": "3.2.30",
"@remotion/lottie": "3.2.30",
"@remotion/media-utils": "3.2.30",
"@remotion/motion-blur": "3.2.30",
"@remotion/paths": "3.2.30",
"@remotion/player": "3.2.30",
"@remotion/preload": "3.2.30",
Expand Down
9 changes: 9 additions & 0 deletions packages/docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ module.exports = {
"visualize-audio",
],
},
{
type: "category",
label: "@remotion/motion-blur",
link: {
type: "doc",
id: "motion-blur/index",
},
items: ["motion-blur/motion-blur"],
},
{
type: "category",
label: "@remotion/lambda",
Expand Down
3 changes: 3 additions & 0 deletions packages/motion-blur/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@jonny"
}
8 changes: 8 additions & 0 deletions packages/motion-blur/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dist/test/**
src
.eslintrc
tsconfig.tsbuildinfo
.prettierrc
jest.config.js
*.tgz
.turbo

1 comment on commit 020684b

@vercel
Copy link

@vercel vercel bot commented on 020684b Oct 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.