-
-
Notifications
You must be signed in to change notification settings - Fork 962
/
make-star.ts
105 lines (94 loc) 路 2.61 KB
/
make-star.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copied from https://stackblitz.com/edit/svg-star-generator?file=index.js
import type {Instruction} from '@remotion/paths';
import {
PathInternals,
reduceInstructions,
resetPath,
serializeInstructions,
} from '@remotion/paths';
import {joinPoints} from './join-points';
import type {ShapeInfo} from './shape-info';
export type MakeStarProps = {
points: number;
innerRadius: number;
outerRadius: number;
edgeRoundness?: number | null;
cornerRadius?: number;
};
export type StarProps = {
centerX: number;
centerY: number;
points: number;
innerRadius: number;
outerRadius: number;
edgeRoundness: number | null;
cornerRadius: number;
};
/**
* @description Generates a star SVG path.
* @param {Number} innerRadius The inner radius of the star.
* @param {Number} outerRadius The outer radius of the star.
* @param {Number} points The amount of points of the star.
* @param {Number} cornerRadius Rounds the corner using an arc. Similar to CSS's border-radius. Cannot be used together with edgeRoundness.
* @param {null|Number} edgeRoundness Allows to modify the shape by rounding the edges using bezier curves. Default null.
* @see [Documentation](https://www.remotion.dev/docs/shapes/make-star)
*/
const star = ({
centerX,
centerY,
points,
innerRadius,
outerRadius,
cornerRadius,
edgeRoundness,
}: StarProps): Instruction[] => {
const degreeIncrement = (Math.PI * 2) / (points * 2);
const d = new Array(points * 2).fill(true).map((_p, i): [number, number] => {
const radius = i % 2 === 0 ? outerRadius : innerRadius;
const angle = degreeIncrement * i - Math.PI / 2;
const point = {
x: centerX + radius * Math.cos(angle),
y: centerY + radius * Math.sin(angle),
};
return [point.x, point.y];
});
return [
...joinPoints([...d, d[0]], {
edgeRoundness,
cornerRadius,
roundCornerStrategy: cornerRadius > 0 ? 'bezier' : 'arc',
}),
{type: 'Z'},
];
};
export const makeStar = ({
points,
innerRadius,
outerRadius,
cornerRadius = 0,
edgeRoundness = null,
}: MakeStarProps): ShapeInfo => {
const width = outerRadius * 2;
const height = outerRadius * 2;
const centerX = width / 2;
const centerY = height / 2;
const starPathInstructions = star({
centerX,
centerY,
points,
innerRadius,
outerRadius,
cornerRadius,
edgeRoundness,
});
const reduced = reduceInstructions(starPathInstructions);
const path = resetPath(serializeInstructions(reduced));
const boundingBox = PathInternals.getBoundingBoxFromInstructions(reduced);
return {
path,
width: boundingBox.width,
height: boundingBox.height,
transformOrigin: `${centerX} ${centerY}`,
instructions: starPathInstructions,
};
};