Skip to content

Commit 9c44958

Browse files
committed
Use more descriptive variable names and add comments
1 parent 984012c commit 9c44958

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

src/index.ts

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,71 +11,87 @@ export function getSvgPath({
1111
width,
1212
height,
1313
}: FigmaSquircleParams) {
14-
cornerRadius = Math.min(cornerRadius, width / 2, height / 2)
14+
const maxRadius = Math.min(width, height) / 2
15+
cornerRadius = Math.min(cornerRadius, maxRadius)
1516

16-
// Keeping these variable names the same as the original code for now
17+
// The article from figma's blog
18+
// https://www.figma.com/blog/desperately-seeking-squircles/
19+
//
20+
// The original code
1721
// https://github.com/MartinRGB/Figma_Squircles_Approximation/blob/bf29714aab58c54329f3ca130ffa16d39a2ff08c/js/rounded-corners.js#L64
18-
const shortest_l = Math.min(width, height)
1922

20-
const p = Math.min(shortest_l / 2, (1 + cornerSmoothing) * cornerRadius)
23+
// 12.2 from the article
24+
const p = Math.min((1 + cornerSmoothing) * cornerRadius, maxRadius)
2125

22-
let angle_alpha: number, angle_beta: number
23-
if (cornerRadius > shortest_l / 4) {
24-
const change_percentage = (cornerRadius - shortest_l / 4) / (shortest_l / 4)
25-
angle_beta = 90 * (1 - cornerSmoothing * (1 - change_percentage))
26-
angle_alpha = 45 * cornerSmoothing * (1 - change_percentage)
26+
let angleAlpha: number, angleBeta: number
27+
28+
if (cornerRadius <= maxRadius / 2) {
29+
angleBeta = 90 * (1 - cornerSmoothing)
30+
angleAlpha = 45 * cornerSmoothing
2731
} else {
28-
angle_beta = 90 * (1 - cornerSmoothing)
29-
angle_alpha = 45 * cornerSmoothing
32+
// When `cornerRadius` is larger and `maxRadius / 2`,
33+
// these angles also depend on `cornerRadius` and `maxRadius / 2`
34+
//
35+
// I did a few tests in Figma and this code generated similar but not identical results
36+
// `diffRatio` was called `change_percentage` in the orignal code
37+
const diffRatio = (cornerRadius - maxRadius / 2) / (maxRadius / 2)
38+
39+
angleBeta = 90 * (1 - cornerSmoothing * (1 - diffRatio))
40+
angleAlpha = 45 * cornerSmoothing * (1 - diffRatio)
3041
}
3142

32-
const angle_theta = (90 - angle_beta) / 2
43+
const angleTheta = (90 - angleBeta) / 2
44+
45+
// This was called `h_longest` in the original code
46+
// In the article this is the distance between 2 control points: P3 and P4
47+
const p3ToP4Distance = cornerRadius * Math.tan(toRadians(angleTheta / 2))
3348

34-
const d_div_c = Math.tan(toRadians(angle_alpha))
35-
const h_longest = cornerRadius * Math.tan(toRadians(angle_theta / 2))
49+
// This was called `l` in the original code
50+
const circularSectionLength =
51+
Math.sin(toRadians(angleBeta / 2)) * cornerRadius * Math.sqrt(2)
3652

37-
const l =
38-
Math.sin(toRadians(angle_beta / 2)) * cornerRadius * Math.pow(2, 1 / 2)
39-
const c = h_longest * Math.cos(toRadians(angle_alpha))
40-
const d = c * d_div_c
41-
const b = (p - l - (1 + d_div_c) * c) / 3
53+
// a, b, c and d are from 11.1 in the article
54+
const c = p3ToP4Distance * Math.cos(toRadians(angleAlpha))
55+
const d = c * Math.tan(toRadians(angleAlpha))
56+
const b = (p - circularSectionLength - c - d) / 3
4257
const a = 2 * b
4358

4459
return `
45-
M ${width / 2} 0
46-
L ${Math.max(width / 2, width - p)} 0
60+
M ${Math.max(width / 2, width - p)} 0
4761
C ${width - (p - a)} 0 ${width - (p - a - b)} 0 ${width -
4862
(p - a - b - c)} ${d}
49-
a ${cornerRadius} ${cornerRadius} 0 0 1 ${l} ${l}
63+
a ${cornerRadius} ${cornerRadius} 0 0 1 ${circularSectionLength} ${circularSectionLength}
5064
C ${width} ${p - a - b}
5165
${width} ${p - a}
5266
${width} ${Math.min(height / 2, p)}
5367
L ${width} ${Math.max(height / 2, height - p)}
5468
C ${width} ${height - (p - a)}
5569
${width} ${height - (p - a - b)}
5670
${width - d} ${height - (p - a - b - c)}
57-
a ${cornerRadius} ${cornerRadius} 0 0 1 -${l} ${l}
71+
a ${cornerRadius} ${cornerRadius} 0 0 1 -${circularSectionLength} ${circularSectionLength}
5872
C ${width - (p - a - b)} ${height}
5973
${width - (p - a)} ${height}
6074
${Math.max(width / 2, width - p)} ${height}
6175
L ${Math.min(width / 2, p)} ${height}
6276
C ${p - a} ${height}
6377
${p - a - b} ${height}
6478
${p - a - b - c} ${height - d}
65-
a ${cornerRadius} ${cornerRadius} 0 0 1 -${l} -${l}
79+
a ${cornerRadius} ${cornerRadius} 0 0 1 -${circularSectionLength} -${circularSectionLength}
6680
C 0 ${height - (p - a - b)}
6781
0 ${height - (p - a)}
6882
0 ${Math.max(height / 2, height - p)}
6983
L 0 ${Math.min(height / 2, p)}
7084
C 0 ${p - a}
7185
0 ${p - a - b}
7286
${d} ${p - a - b - c}
73-
a ${cornerRadius} ${cornerRadius} 0 0 1 ${l} -${l}
87+
a ${cornerRadius} ${cornerRadius} 0 0 1 ${circularSectionLength} -${circularSectionLength}
7488
C ${p - a - b} 0
7589
${p - a} 0
7690
${+Math.min(width / 2, p)} 0
7791
Z
78-
`.replace(/[\t\s\n]+/g, ' ')
92+
`
93+
.replace(/[\t\s\n]+/g, ' ')
94+
.trim()
7995
}
8096

8197
function toRadians(degrees: number) {

0 commit comments

Comments
 (0)