Skip to content

Commit 993aae3

Browse files
committed
refactor: update Knot components for improved SVG rendering and styling
- Replaced petal path calculations with fixed SVG paths for vertical and horizontal loops in both KnotBackground and KnotLogo components. - Adjusted stroke width and viewBox dimensions for better visual consistency across components. - Simplified the rendering logic by removing unnecessary calculations and utilizing direct path definitions.
1 parent 06d6b45 commit 993aae3

2 files changed

Lines changed: 50 additions & 109 deletions

File tree

components/knot-background.tsx

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,19 @@
22

33
import { useId, useMemo } from 'react'
44

5-
const cx = 50
6-
const cy = 50
7-
const R = 50
8-
const loopR = 22
9-
const ANGLES = [0, 60, 120, 180, 240, 300]
5+
const VERTICAL_LOOP =
6+
'M176 132 C224 80,288 80,336 132 C368 168,368 344,336 380 C288 432,224 432,176 380 C144 344,144 168,176 132Z'
107

11-
function petalPath(deg: number): string {
12-
const rad = (deg * Math.PI) / 180
13-
const px = cx + R * 0.42 * Math.cos(rad)
14-
const py = cy + R * 0.42 * Math.sin(rad)
15-
16-
const tangent = rad + Math.PI / 2
17-
const cp1x = px + loopR * 1.1 * Math.cos(tangent)
18-
const cp1y = py + loopR * 1.1 * Math.sin(tangent)
19-
const cp2x = px - loopR * 1.1 * Math.cos(tangent)
20-
const cp2y = py - loopR * 1.1 * Math.sin(tangent)
21-
22-
const tipDist = loopR * 1.55
23-
const tipX = cx + (R * 0.42 + tipDist) * Math.cos(rad)
24-
const tipY = cy + (R * 0.42 + tipDist) * Math.sin(rad)
25-
26-
const inTan1 = rad + 0.65
27-
const inTan2 = rad - 0.65
28-
const cpInnerR = loopR * 1.4
29-
30-
return `M ${cx.toFixed(1)} ${cy.toFixed(1)} C ${cp1x.toFixed(1)} ${cp1y.toFixed(1)}, ${(tipX + cpInnerR * Math.cos(inTan1)).toFixed(1)} ${(tipY + cpInnerR * Math.sin(inTan1)).toFixed(1)}, ${tipX.toFixed(1)} ${tipY.toFixed(1)} C ${(tipX + cpInnerR * Math.cos(inTan2)).toFixed(1)} ${(tipY + cpInnerR * Math.sin(inTan2)).toFixed(1)}, ${cp2x.toFixed(1)} ${cp2y.toFixed(1)}, ${cx.toFixed(1)} ${cy.toFixed(1)}`
31-
}
32-
33-
const PETAL_PATHS = ANGLES.map(petalPath)
8+
const HORIZONTAL_LOOP =
9+
'M132 176 C80 224,80 288,132 336 C168 368,344 368,380 336 C432 288,432 224,380 176 C344 144,168 144,132 176Z'
3410

3511
const FLOATERS = [
3612
{ size: 340, x: '-6%', y: '-10%', delay: '0s', dur: '50s' },
3713
{ size: 280, x: '72%', y: '55%', delay: '-20s', dur: '58s' },
3814
{ size: 220, x: '35%', y: '82%', delay: '-35s', dur: '44s' },
3915
] as const
4016

41-
function KnotPaths({ strokeWidth = 1.6, opacity = 1 }: { strokeWidth?: number; opacity?: number }) {
17+
function KnotPaths({ strokeWidth = 14, opacity = 1 }: { strokeWidth?: number; opacity?: number }) {
4218
return (
4319
<g
4420
style={{ stroke: 'var(--brand)' }}
@@ -48,9 +24,14 @@ function KnotPaths({ strokeWidth = 1.6, opacity = 1 }: { strokeWidth?: number; o
4824
fill="none"
4925
opacity={opacity}
5026
>
51-
{PETAL_PATHS.map((d, i) => (
52-
<path key={i} d={d} opacity={i % 2 === 0 ? 1 : 0.65} />
53-
))}
27+
<path d={VERTICAL_LOOP} />
28+
<path d={HORIZONTAL_LOOP} />
29+
<g transform="rotate(45 256 256)">
30+
<path d={VERTICAL_LOOP} />
31+
</g>
32+
<g transform="rotate(-45 256 256)">
33+
<path d={VERTICAL_LOOP} />
34+
</g>
5435
</g>
5536
)
5637
}
@@ -70,9 +51,9 @@ export function KnotBackground() {
7051
>
7152
<defs>
7253
<pattern id={`kp${pid}`} width="120" height="120" patternUnits="userSpaceOnUse">
73-
<g transform="translate(10,10) scale(1)">
74-
<KnotPaths strokeWidth={1.5} />
75-
</g>
54+
<svg viewBox="0 0 512 512" width="100" height="100">
55+
<KnotPaths strokeWidth={12} />
56+
</svg>
7657
</pattern>
7758
</defs>
7859
<rect width="100%" height="100%" fill={`url(#kp${pid})`} />
@@ -92,17 +73,22 @@ export function KnotBackground() {
9273
animationDuration: f.dur,
9374
}}
9475
>
95-
<svg viewBox="0 0 100 100" fill="none" width="100%" height="100%">
76+
<svg viewBox="0 0 512 512" fill="none" width="100%" height="100%">
9677
<g
9778
style={{ stroke: 'var(--mode-accent, var(--brand))' }}
98-
strokeWidth={3.5}
79+
strokeWidth={36}
9980
strokeLinecap="round"
10081
strokeLinejoin="round"
10182
fill="none"
10283
>
103-
{PETAL_PATHS.map((d, j) => (
104-
<path key={j} d={d} opacity={j % 2 === 0 ? 1 : 0.7} />
105-
))}
84+
<path d={VERTICAL_LOOP} />
85+
<path d={HORIZONTAL_LOOP} />
86+
<g transform="rotate(45 256 256)">
87+
<path d={VERTICAL_LOOP} />
88+
</g>
89+
<g transform="rotate(-45 256 256)">
90+
<path d={VERTICAL_LOOP} />
91+
</g>
10692
</g>
10793
</svg>
10894
</div>

components/knot-logo.tsx

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,48 @@
11
'use client'
22

3-
import { useId } from 'react'
4-
53
interface KnotLogoProps {
64
size?: number
75
className?: string
86
color?: string
7+
strokeWidth?: number
98
}
109

11-
/**
12-
* Celtic-style interwoven knot with 6 radiating loops.
13-
* Inspired by the OpenKnots brand mark — each loop weaves
14-
* over-and-under its neighbours via stroke masks.
15-
*/
16-
export function KnotLogo({ size = 24, className, color }: KnotLogoProps) {
17-
const uid = useId()
18-
const c = color || 'currentColor'
19-
const id = uid.replace(/:/g, '')
20-
21-
const R = 50
22-
const cx = 50
23-
const cy = 50
24-
const loopR = 22
25-
const sw = 5.8
26-
27-
const angles = [0, 60, 120, 180, 240, 300]
28-
29-
const petalPaths = angles.map((deg) => {
30-
const rad = (deg * Math.PI) / 180
31-
const px = cx + R * 0.42 * Math.cos(rad)
32-
const py = cy + R * 0.42 * Math.sin(rad)
10+
const VERTICAL_LOOP =
11+
'M176 132 C224 80,288 80,336 132 C368 168,368 344,336 380 C288 432,224 432,176 380 C144 344,144 168,176 132Z'
3312

34-
const tangent = rad + Math.PI / 2
35-
const cp1x = px + loopR * 1.1 * Math.cos(tangent)
36-
const cp1y = py + loopR * 1.1 * Math.sin(tangent)
37-
const cp2x = px - loopR * 1.1 * Math.cos(tangent)
38-
const cp2y = py - loopR * 1.1 * Math.sin(tangent)
13+
const HORIZONTAL_LOOP =
14+
'M132 176 C80 224,80 288,132 336 C168 368,344 368,380 336 C432 288,432 224,380 176 C344 144,168 144,132 176Z'
3915

40-
const tipDist = loopR * 1.55
41-
const tipX = cx + (R * 0.42 + tipDist) * Math.cos(rad)
42-
const tipY = cy + (R * 0.42 + tipDist) * Math.sin(rad)
43-
44-
const inTan1 = rad + 0.65
45-
const inTan2 = rad - 0.65
46-
const cpInnerR = loopR * 1.4
47-
48-
return `M ${cx.toFixed(1)} ${cy.toFixed(1)} C ${cp1x.toFixed(1)} ${cp1y.toFixed(1)}, ${(tipX + cpInnerR * Math.cos(inTan1)).toFixed(1)} ${(tipY + cpInnerR * Math.sin(inTan1)).toFixed(1)}, ${tipX.toFixed(1)} ${tipY.toFixed(1)} C ${(tipX + cpInnerR * Math.cos(inTan2)).toFixed(1)} ${(tipY + cpInnerR * Math.sin(inTan2)).toFixed(1)}, ${cp2x.toFixed(1)} ${cp2y.toFixed(1)}, ${cx.toFixed(1)} ${cy.toFixed(1)}`
49-
})
16+
export function KnotLogo({ size = 24, className, color, strokeWidth = 56 }: KnotLogoProps) {
17+
const c = color || 'currentColor'
5018

5119
return (
5220
<svg
5321
width={size}
5422
height={size}
55-
viewBox="0 0 100 100"
23+
viewBox="0 0 512 512"
5624
fill="none"
5725
xmlns="http://www.w3.org/2000/svg"
5826
className={className}
5927
aria-label="KnotCode"
6028
role="img"
6129
>
62-
<defs>
63-
{petalPaths.map((_, i) => {
64-
const nextIdx = (i + 1) % 6
65-
const nextDeg = angles[nextIdx]
66-
const nextRad = (nextDeg * Math.PI) / 180
67-
const mskX = cx + R * 0.32 * Math.cos(nextRad)
68-
const mskY = cy + R * 0.32 * Math.sin(nextRad)
69-
return (
70-
<mask key={`m${i}`} id={`${id}m${i}`}>
71-
<rect width="100" height="100" fill="white" />
72-
<circle cx={mskX} cy={mskY} r={sw + 3} fill="black" />
73-
</mask>
74-
)
75-
})}
76-
</defs>
77-
78-
{petalPaths.map((d, i) => (
79-
<path
80-
key={i}
81-
d={d}
82-
stroke={c}
83-
strokeWidth={sw}
84-
strokeLinecap="round"
85-
strokeLinejoin="round"
86-
fill="none"
87-
mask={`url(#${id}m${i})`}
88-
opacity={i % 2 === 0 ? 1 : 0.7}
89-
/>
90-
))}
30+
<g
31+
stroke={c}
32+
strokeWidth={strokeWidth}
33+
strokeLinecap="round"
34+
strokeLinejoin="round"
35+
fill="none"
36+
>
37+
<path d={VERTICAL_LOOP} />
38+
<path d={HORIZONTAL_LOOP} />
39+
<g transform="rotate(45 256 256)">
40+
<path d={VERTICAL_LOOP} />
41+
</g>
42+
<g transform="rotate(-45 256 256)">
43+
<path d={VERTICAL_LOOP} />
44+
</g>
45+
</g>
9146
</svg>
9247
)
9348
}

0 commit comments

Comments
 (0)