Skip to content

Commit 7cfa360

Browse files
committed
finish warpPath()
1 parent d60892f commit 7cfa360

File tree

7 files changed

+110
-3
lines changed

7 files changed

+110
-3
lines changed

packages/docs/components/TableOfContents/paths.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export const TableOfContents: React.FC = () => {
4141
<strong>translatePath()</strong>
4242
<div>Translates the position of an path against X/Y coordinates</div>
4343
</TOCItem>
44+
<TOCItem link="/docs/paths/warp-path">
45+
<strong>warpPath()</strong>
46+
<div>Remap the coordinates of a path</div>
47+
</TOCItem>
4448
<TOCItem link="/docs/paths/get-bounding-box">
4549
<strong>getBoundingBox()</strong>
4650
<div>Get the bounding box of a SVG path</div>

packages/docs/docs/paths/warp-path.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
image: /generated/articles-docs-paths-warp-path.png
3+
title: warpPath()
4+
crumb: "@remotion/paths"
5+
---
6+
7+
_Part of the [`@remotion/paths`](/docs/paths) package. Available from v3.3.43_
8+
9+
Allows you to remap the coordinates of an SVG using a function in order to create a warp effect.
10+
11+
```tsx twoslash title="warp-path.ts"
12+
import { warpPath, WarpPathFn } from "@remotion/paths";
13+
14+
const fn: WarpPathFn = ({ x, y }) => ({
15+
x: x + Math.sin(y / 4) * 5,
16+
y: y,
17+
});
18+
19+
const newPath = warpPath("M 0 0 L 0 100", fn); // M 0 0 L 0.970365514464549 0.78125 L 1.9038320449619508 1.5625 L 2.7649037231526368 2.34375...;
20+
```
21+
22+
<table>
23+
<tr>
24+
<th align="center">
25+
Input
26+
</th>
27+
<th align="center">
28+
Output
29+
</th>
30+
</tr>
31+
<tr>
32+
<td align="center">
33+
<svg viewBox="-20 0 40 100" style={{height: 100}}>
34+
<path d="M 0 0 L 0 100" stroke="black" strokeWidth={3}></path>
35+
</svg>
36+
</td>
37+
<td align="center">
38+
<svg viewBox="-20 0 40 100" style={{height: 100}}>
39+
<path d="M 0 0 L 0.970365514464549 0.78125 L 1.9038320449619508 1.5625 L 2.7649037231526368 2.34375 L 3.5208375572726687 3.125 L 4.142888512580358 3.90625 L 4.607402566045721 4.6875 L 4.896716170937308 5.46875 L 4.999827928391245 6.25 L 4.912816925072913 7.03125 L 4.6389918292815775 7.8125 L 4.1887650759902435 8.59375 L 3.5792569250428965 9.375 L 2.8336444485370142 10.15625 L 1.9802802027065005 10.9375 L 1.0516140975653265 11.71875 L 0.08295946114673952 12.5 L -0.8888497801925157 13.28125 L -1.826859743528138 14.0625 L -2.6954017925759493 14.84375 L -3.461448868289758 15.625 L -4.095871371210911 16.40625 L -4.574544839562133 17.1875 L -4.879267302672675 17.96875 L -4.998451426581117 18.75 L -4.927565132383498 19.53125 L -4.669303932434802 20.3125 L -4.23348843117139 21.09375 L -3.6366908881738444 21.875 L -2.901605043731207 22.65625 L -2.0561831698319675 23.4375 L -1.132573160960709 24.21875 L -0.16589608273778408 25 L 0.8070893368327121 25.78125 L 1.7493844896367943 26.5625 L 2.625157791372104 27.34375 L 3.4011072083844276 28.125 L 4.047726596163411 28.90625 L 4.540427695886122 29.6875 L 4.860475124124084 30.46875 L 4.99569880192535 31.25 L 4.940956732542519 32.03125 L 4.698330530285226 32.8125 L 4.277046265344189 33.59375 L 3.693123634530507 34.375 L 2.968766798514854 35.15625 L 2.131520049504873 35.9375 L 1.2132204158241793 36.71875 L 0.24878703150539308 37.5 L -0.7251066938394417 38.28125 L -1.671427612987411 39.0625 L -2.5541910584055962 39.84375 L -3.3398291902092057 40.625 L -3.998467442168012 41.40625 L -4.505060527802941 42.1875 L -4.840344808963141 42.96875 L -4.991570812248588 43.75 L -4.952988038710723 44.53125 L -4.726063631524939 45.3125 L -4.31942658660843 46.09375 L -3.748539627622706 46.875 L -3.0351112225962185 47.65625 L -2.206270100741183 48.4375 L -1.293533659173177 49.21875 L -0.33160948675600344 50 L 0.6429244218407533 50.78125 L 1.5930105758749626 51.5625 L 2.4825211315160853 52.34375 L 3.277631684205266 53.125 L 3.9481074707543513 53.90625 L 4.468453072241857 54.6875 L 4.8188818992636255 55.46875 L 4.986068594026995 56.25 L 4.963655738551176 57.03125 L 4.752495600958368 57.8125 L 4.360617727244791 58.59375 L 3.8029236108824334 59.375 L 3.100620050702746 60.15625 L 2.280412744116503 60.9375 L 1.3734907799817961 61.71875 L 0.41434064665299114 62.5 L -0.5605651464245245 63.28125 L -1.5141549672811254 64.0625 L -2.410167742139434 64.84375 L -3.2145318139578256 65.625 L -3.896660546517933 66.40625 L -4.430615407595479 67.1875 L -4.7960923039756995 67.96875 L -4.97919366207537 68.75 L -4.972956895141175 69.53125 L -4.777619161604328 70.3125 L -4.400608346927072 71.09375 L -3.8562606118641445 71.875 L -3.165275247609673 72.65625 L -2.3539275674317985 73.4375 L -1.45306976526817 74.21875 L -0.49695773449424085 75 L 0.47805154190941496 75.78125 L 1.4348824969306184 76.5625 L 2.337150809875451 77.34375 L 3.150546951481852 78.125 L 3.8441408333030616 78.90625 L 4.391557950945079 79.6875 L 4.771982297299119 80.46875 L 4.970947909130105 81.25 L 4.980888947780822 82.03125 L 4.801427396699442 82.8125 L 4.439387435844302 83.59375 L 3.9085359463668135 84.375 L 3.229059013105301 85.15625 L 2.426794331333073 85.9375 L 1.5322487061548606 86.71875 L 0.5794380049827966 87.5 L -0.3954063251024031 88.28125 L -1.3552149893143026 89.0625 L -2.2634904370038287 89.84375 L -3.0856947124393805 90.625 L -3.7905627903034036 91.40625 L -4.351291455192668 92.1875 L -4.746558516955883 92.96875 L -4.9613336053280985 93.75 L -4.987449712697998 94.53125 L -4.823913751602394 95.3125 L -4.476944317731847 96.09375 L -3.9597352224766382 96.875 L -3.2919537868915727 97.65625 L -2.4989929748834614 98.4375 L -1.6110058039005881 99.21875 L -0.6617587504888651 100" fill="transparent" stroke="black" strokeWidth={3}></path>
40+
</svg>
41+
</td>
42+
</tr>
43+
</table>
44+
45+
## How it works
46+
47+
This function works by splitting SVG instructions into many smaller SVG instructions and then remapping the coordinates of each instruction. This will result in the output being a much SVG path than the input.
48+
49+
## Arguments
50+
51+
### `path`
52+
53+
An SVG path string.
54+
55+
### `fn`
56+
57+
A function that takes the coordinates of the SVG path and returns the new coordinates. The type of the function is `WarpPathFn` which can also be imported from `@remotion/paths`.
58+
59+
```tsx twoslash
60+
import { WarpPathFn } from "@remotion/paths";
61+
62+
const fn: WarpPathFn = ({ x, y }) => ({
63+
x: x + Math.sin(y / 4) * 5,
64+
y: y,
65+
});
66+
```
67+
68+
### `options`
69+
70+
#### `interpolationThreshold`
71+
72+
The [interpolation algorithm](/docs/paths/warp-path#how-it-works) will split the SVG path recursively into smaller SVG paths. This option allows you to specify the distance of a segment at which the algorithm should stop dividing the path into smaller segments.
73+
74+
Since SVG is unitless, the threshold is measured in SVG units.
75+
76+
By default the threshold is the 1% width or height of the [bounding box](/docs/paths/get-bounding-box) of the path, whichever is bigger. In other terms, it is `Math.max(width, height) * 0.01`.
77+
78+
## See also
79+
80+
- [`@remotion/paths`](/docs/paths)
81+
- [Source code for this function](https://github.com/remotion-dev/remotion/blob/main/packages/paths/src/warp-path.ts)

packages/docs/sidebars.js

+2
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,13 @@ module.exports = {
262262
"paths/reset-path",
263263
"paths/get-subpaths",
264264
"paths/translate-path",
265+
"paths/warp-path",
265266
"paths/get-bounding-box",
266267
"paths/extend-viewbox",
267268
"paths/parse-path",
268269
"paths/serialize-instructions",
269270
"paths/reduce-instructions",
271+
270272
"paths/get-parts",
271273
],
272274
},

packages/docs/src/data/articles.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,13 @@ export const articles = [
13031303
compId: "articles-docs-paths-translate-path",
13041304
crumb: "@remotion/paths",
13051305
},
1306+
{
1307+
id: "paths/warp-path",
1308+
title: "warpPath()",
1309+
relativePath: "docs/paths/warp-path.md",
1310+
compId: "articles-docs-paths-warp-path",
1311+
crumb: "@remotion/paths",
1312+
},
13061313
{
13071314
id: "performance",
13081315
title: "Performance Tips",
Loading

packages/example/src/WarpText/demo2.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ export const WarpDemo2 = () => {
5959
const height = boundingBox.y2 - boundingBox.y1;
6060

6161
const start = 0.4 * height;
62-
const end = 0.5 * height;
62+
const end = 0.47 * height;
6363

6464
const warpPathFn: WarpPathFn = ({x, y}) => {
6565
const currentPos = y - start;
6666

6767
const ease = normalDistribution(currentPos / (end - start));
6868

6969
return {
70-
x: x + 80 * ease,
70+
x: x + 50 * ease,
7171
y: y * 5,
7272
};
7373
};
@@ -98,7 +98,7 @@ export const WarpDemo2 = () => {
9898
d={warped}
9999
fill="transparent"
100100
stroke="#E2BECC"
101-
strokeWidth={2}
101+
strokeWidth={3}
102102
/>
103103
</svg>
104104
) : null}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import {expect, test} from 'vitest';
2+
import {warpPath} from '../warp-path';
3+
4+
test('Should be able to warp path', () => {
5+
expect(
6+
warpPath('M 0 0 L 0 100', ({x, y}) => ({
7+
x: x + Math.sin(y / 4) * 5,
8+
y,
9+
}))
10+
).toBe(
11+
'M 0 0 L 0.970365514464549 0.78125 L 1.9038320449619508 1.5625 L 2.7649037231526368 2.34375 L 3.5208375572726687 3.125 L 4.142888512580358 3.90625 L 4.607402566045721 4.6875 L 4.896716170937308 5.46875 L 4.999827928391245 6.25 L 4.912816925072913 7.03125 L 4.6389918292815775 7.8125 L 4.1887650759902435 8.59375 L 3.5792569250428965 9.375 L 2.8336444485370142 10.15625 L 1.9802802027065005 10.9375 L 1.0516140975653265 11.71875 L 0.08295946114673952 12.5 L -0.8888497801925157 13.28125 L -1.826859743528138 14.0625 L -2.6954017925759493 14.84375 L -3.461448868289758 15.625 L -4.095871371210911 16.40625 L -4.574544839562133 17.1875 L -4.879267302672675 17.96875 L -4.998451426581117 18.75 L -4.927565132383498 19.53125 L -4.669303932434802 20.3125 L -4.23348843117139 21.09375 L -3.6366908881738444 21.875 L -2.901605043731207 22.65625 L -2.0561831698319675 23.4375 L -1.132573160960709 24.21875 L -0.16589608273778408 25 L 0.8070893368327121 25.78125 L 1.7493844896367943 26.5625 L 2.625157791372104 27.34375 L 3.4011072083844276 28.125 L 4.047726596163411 28.90625 L 4.540427695886122 29.6875 L 4.860475124124084 30.46875 L 4.99569880192535 31.25 L 4.940956732542519 32.03125 L 4.698330530285226 32.8125 L 4.277046265344189 33.59375 L 3.693123634530507 34.375 L 2.968766798514854 35.15625 L 2.131520049504873 35.9375 L 1.2132204158241793 36.71875 L 0.24878703150539308 37.5 L -0.7251066938394417 38.28125 L -1.671427612987411 39.0625 L -2.5541910584055962 39.84375 L -3.3398291902092057 40.625 L -3.998467442168012 41.40625 L -4.505060527802941 42.1875 L -4.840344808963141 42.96875 L -4.991570812248588 43.75 L -4.952988038710723 44.53125 L -4.726063631524939 45.3125 L -4.31942658660843 46.09375 L -3.748539627622706 46.875 L -3.0351112225962185 47.65625 L -2.206270100741183 48.4375 L -1.293533659173177 49.21875 L -0.33160948675600344 50 L 0.6429244218407533 50.78125 L 1.5930105758749626 51.5625 L 2.4825211315160853 52.34375 L 3.277631684205266 53.125 L 3.9481074707543513 53.90625 L 4.468453072241857 54.6875 L 4.8188818992636255 55.46875 L 4.986068594026995 56.25 L 4.963655738551176 57.03125 L 4.752495600958368 57.8125 L 4.360617727244791 58.59375 L 3.8029236108824334 59.375 L 3.100620050702746 60.15625 L 2.280412744116503 60.9375 L 1.3734907799817961 61.71875 L 0.41434064665299114 62.5 L -0.5605651464245245 63.28125 L -1.5141549672811254 64.0625 L -2.410167742139434 64.84375 L -3.2145318139578256 65.625 L -3.896660546517933 66.40625 L -4.430615407595479 67.1875 L -4.7960923039756995 67.96875 L -4.97919366207537 68.75 L -4.972956895141175 69.53125 L -4.777619161604328 70.3125 L -4.400608346927072 71.09375 L -3.8562606118641445 71.875 L -3.165275247609673 72.65625 L -2.3539275674317985 73.4375 L -1.45306976526817 74.21875 L -0.49695773449424085 75 L 0.47805154190941496 75.78125 L 1.4348824969306184 76.5625 L 2.337150809875451 77.34375 L 3.150546951481852 78.125 L 3.8441408333030616 78.90625 L 4.391557950945079 79.6875 L 4.771982297299119 80.46875 L 4.970947909130105 81.25 L 4.980888947780822 82.03125 L 4.801427396699442 82.8125 L 4.439387435844302 83.59375 L 3.9085359463668135 84.375 L 3.229059013105301 85.15625 L 2.426794331333073 85.9375 L 1.5322487061548606 86.71875 L 0.5794380049827966 87.5 L -0.3954063251024031 88.28125 L -1.3552149893143026 89.0625 L -2.2634904370038287 89.84375 L -3.0856947124393805 90.625 L -3.7905627903034036 91.40625 L -4.351291455192668 92.1875 L -4.746558516955883 92.96875 L -4.9613336053280985 93.75 L -4.987449712697998 94.53125 L -4.823913751602394 95.3125 L -4.476944317731847 96.09375 L -3.9597352224766382 96.875 L -3.2919537868915727 97.65625 L -2.4989929748834614 98.4375 L -1.6110058039005881 99.21875 L -0.6617587504888651 100'
12+
);
13+
});

0 commit comments

Comments
 (0)