Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 29 additions & 46 deletions packages/badge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,6 @@ const generateFontStyle = (): string => `
</style>
`

const generateGlowFilter = (
floodColor: string,
floodOpacity: number,
stdDeviation: number,
): string => `
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceAlpha" stdDeviation="${stdDeviation}" result="blur" />
<feFlood flood-color="${floodColor}" flood-opacity="${floodOpacity}" result="color" />
<feComposite in="color" in2="blur" operator="in" result="glow" />
<feMerge>
<feMergeNode in="glow" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
`

const generateTrailingLight = (
width: number,
height: number,
Expand All @@ -45,10 +29,10 @@ const generateTrailingLight = (

const r = BADGE_CONFIG.borderRadius
const perimeter = 2 * (width - 2 * r) + 2 * (height - 2 * r) + 2 * Math.PI * r
const blobCount = 3
const blobCount = 5
const blobRadius = Math.min(height, Math.max(16, Math.round(perimeter / 12)))
const dur = Math.max(3, perimeter / 60)
const gap = 0.3
const gap = 0.12

const path = `M${ox + r},${oy} H${ox + width - r} Q${ox + width},${oy} ${ox + width},${oy + r} V${oy + height - r} Q${ox + width},${oy + height} ${ox + width - r},${oy + height} H${ox + r} Q${ox},${oy + height} ${ox},${oy + height - r} V${oy + r} Q${ox},${oy} ${ox + r},${oy} Z`

Expand All @@ -66,15 +50,12 @@ const generateTrailingLight = (

return `
<defs>
<filter id="trail-blur" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="4" />
</filter>
<clipPath id="trail-clip">
<rect x="${ox - 2}" y="${oy - 2}" width="${width + 4}" height="${height + 4}" rx="${r + 2}" />
</clipPath>
${gradient}
</defs>
<g filter="url(#trail-blur)" clip-path="url(#trail-clip)">
<g style="filter:blur(4px)" clip-path="url(#trail-clip)">
${blobs}
</g>
`
Expand All @@ -87,41 +68,46 @@ const generateShineEffect = (
ox: number,
oy: number,
): string => {
const shineWidth = Math.round(width * 0.7)
const skewOffset = Math.round(height * 0.36)

return `
<defs>
<clipPath id="shine-clip">
<rect x="${ox + 0.5}" y="${oy + 0.5}" width="${width - 1}" height="${height - 1}" rx="${r - 0.5}" />
</clipPath>
<linearGradient id="shine" gradientUnits="userSpaceOnUse"
x1="${ox}" y1="${oy}" x2="${ox + width}" y2="${oy + height * 2}">
<linearGradient id="shine">
<stop offset="0%" stop-color="white" stop-opacity="0" />
<stop offset="25%" stop-color="white" stop-opacity="0" />
<stop offset="40%" stop-color="white" stop-opacity="0.15" />
<stop offset="50%" stop-color="white" stop-opacity="0.3" />
<stop offset="60%" stop-color="white" stop-opacity="0.15" />
<stop offset="75%" stop-color="white" stop-opacity="0" />
<stop offset="100%" stop-color="white" stop-opacity="0" />
<animateTransform
attributeName="gradientTransform"
type="translate"
values="-${width},0; -${width},0; ${width},0; ${width},0"
keyTimes="0; 0.3; 0.7; 1"
calcMode="spline"
keySplines="0 0 1 1; 0.4 0 0.2 1; 0 0 1 1"
dur="3s"
repeatCount="indefinite"
/>
</linearGradient>
</defs>
<rect
x="${ox}"
y="${oy}"
width="${width}"
height="${height}"
rx="${r}"
fill="url(#shine)"
clip-path="url(#shine-clip)"
/>
<g clip-path="url(#shine-clip)">
<g transform="skewX(-20)">
<rect
x="${ox}"
y="${oy}"
width="${shineWidth}"
height="${height}"
fill="url(#shine)"
>
<animateTransform
attributeName="transform"
type="translate"
values="-${shineWidth + skewOffset},0; -${shineWidth + skewOffset},0; ${width + skewOffset},0; ${width + skewOffset},0"
keyTimes="0; 0.3; 0.7; 1"
calcMode="spline"
keySplines="0 0 1 1; 0.4 0 0.2 1; 0 0 1 1"
dur="3s"
repeatCount="indefinite"
/>
</rect>
</g>
</g>
`
}

Expand All @@ -140,9 +126,7 @@ const generateIcon = (
height="${size}"
viewBox="0 0 24 24"
fill="${color}"
filter="url(#glow)"
xmlns="http://www.w3.org/2000/svg"
style="overflow: visible"
>
<path d="${icon.path}" />
</svg>
Expand Down Expand Up @@ -236,7 +220,6 @@ export const generateBadgeSvg = (
<stop offset="50%" stop-color="${gradMiddle}" />
<stop offset="100%" stop-color="${gradEnd}" />
</linearGradient>
${generateGlowFilter('#808080', 0.4, 3)}
</defs>
<rect
x="${ox}"
Expand Down