Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding motion blur packaging #1392

Merged
merged 10 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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