|
1 | 1 | import { createUniqueId, type ComponentProps } from "solid-js" |
2 | 2 |
|
| 3 | +const CELL = 12 |
| 4 | +const HALF = CELL / 2 |
| 5 | +const LEFT = [ |
| 6 | + "▄ ", |
| 7 | + "█▀▀█ █▀▀▄ █▀▀█ █ █ █▀▀▀ █▀▀█ █▀▀▄", |
| 8 | + "█__█ █___ █__█ █▐▌█ ^^^█ █^^^ █___", |
| 9 | + "▀▀▀▀ ▀~~~ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀~~~", |
| 10 | +] |
| 11 | +const RIGHT = [" ▄ ", "█▀▀▀ █▀▀█ █▀▀█ █▀▀█", "█___ █__█ █__█ █^^^", "▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀"] |
| 12 | +const GAP = 1 |
| 13 | + |
| 14 | +type Rect = { |
| 15 | + x: number |
| 16 | + y: number |
| 17 | + width: number |
| 18 | + height: number |
| 19 | + fill: "fill" | "weak" | "shadow" |
| 20 | +} |
| 21 | + |
| 22 | +function rects(rows: string[], offset: number): Rect[] { |
| 23 | + return rows.flatMap((row, y) => |
| 24 | + [...row].flatMap((char, x): Rect[] => { |
| 25 | + const cell = { x: (offset + x) * CELL, y: y * CELL } |
| 26 | + if (char === "█") return [{ ...cell, width: CELL, height: CELL, fill: "fill" as const }] |
| 27 | + if (char === "▀") return [{ ...cell, width: CELL, height: HALF, fill: "fill" as const }] |
| 28 | + if (char === "▄") return [{ ...cell, y: cell.y + HALF, width: CELL, height: HALF, fill: "fill" as const }] |
| 29 | + if (char === "▐") return [{ ...cell, x: cell.x + HALF, width: HALF, height: CELL, fill: "fill" as const }] |
| 30 | + if (char === "_") return [{ ...cell, width: CELL, height: CELL, fill: "weak" as const }] |
| 31 | + if (char === "^") { |
| 32 | + return [ |
| 33 | + { ...cell, width: CELL, height: CELL, fill: "weak" as const }, |
| 34 | + { ...cell, width: CELL, height: HALF, fill: "fill" as const }, |
| 35 | + ] |
| 36 | + } |
| 37 | + if (char === "~") return [{ ...cell, width: CELL, height: HALF, fill: "shadow" as const }] |
| 38 | + return [] |
| 39 | + }), |
| 40 | + ) |
| 41 | +} |
| 42 | + |
3 | 43 | export function WordmarkV2(props: Pick<ComponentProps<"svg">, "class">) { |
4 | 44 | const filter = createUniqueId() |
5 | 45 | const mask = createUniqueId() |
6 | 46 | const maskGradient = createUniqueId() |
| 47 | + const left = rects(LEFT, 0) |
| 48 | + const right = rects(RIGHT, LEFT[1].length + GAP) |
| 49 | + const width = (LEFT[1].length + GAP + RIGHT[1].length) * CELL |
| 50 | + const height = LEFT.length * CELL |
7 | 51 |
|
8 | 52 | return ( |
9 | 53 | <svg |
10 | 54 | xmlns="http://www.w3.org/2000/svg" |
11 | | - viewBox="0 0 720.002 129.001" |
| 55 | + viewBox={`0 0 ${width} ${height}`} |
12 | 56 | fill="none" |
13 | 57 | preserveAspectRatio="none" |
14 | 58 | classList={{ [props.class ?? ""]: !!props.class }} |
15 | 59 | > |
16 | 60 | <g opacity="0.16" filter={`url(#${filter})`} mask={`url(#${mask})`}> |
17 | | - <path |
18 | | - opacity="0.7" |
19 | | - d="M55.3846 36.8583H18.4615V92.144H55.3846V36.8583ZM73.8462 110.573H0V18.4297H73.8462V110.573Z" |
20 | | - fill="currentColor" |
21 | | - /> |
22 | | - <path |
23 | | - opacity="0.7" |
24 | | - d="M110.774 92.144H147.697V36.8583H110.774V92.144ZM166.159 110.573H110.774V129.001H92.3125V18.4297H166.159V110.573Z" |
25 | | - fill="currentColor" |
26 | | - /> |
27 | | - <path |
28 | | - opacity="0.7" |
29 | | - d="M258.463 73.7154H203.079V92.144H258.463V110.573H184.617V18.4297H258.463V73.7154ZM203.079 55.2868H240.002V36.8583H203.079V55.2868Z" |
30 | | - fill="currentColor" |
31 | | - /> |
32 | | - <path |
33 | | - opacity="0.7" |
34 | | - d="M332.306 36.8583H295.383V110.573H276.922V18.4297H332.306V36.8583ZM350.768 110.573H332.306V36.8583H350.768V110.573Z" |
35 | | - fill="currentColor" |
36 | | - /> |
37 | | - <path |
38 | | - opacity="0.7" |
39 | | - d="M443.081 36.8583H387.696V92.144H443.081V110.573H369.234V18.4297H443.081V36.8583Z" |
40 | | - fill="currentColor" |
41 | | - /> |
42 | | - <path |
43 | | - opacity="0.7" |
44 | | - d="M516.924 36.8583H480.001V92.144H516.924V36.8583ZM535.385 110.573H461.539V18.4297H535.385V110.573Z" |
45 | | - fill="currentColor" |
46 | | - /> |
47 | | - <path |
48 | | - opacity="0.7" |
49 | | - d="M609.228 36.8571H572.305V92.1429H609.228V36.8571ZM627.69 110.571H553.844V18.4286H609.228V0H627.69V110.571Z" |
50 | | - fill="currentColor" |
51 | | - /> |
52 | | - <path |
53 | | - opacity="0.7" |
54 | | - d="M664.618 36.8583V55.2868H701.541V36.8583H664.618ZM720.002 73.7154H664.618V92.144H720.002V110.573H646.156V18.4297H720.002V73.7154Z" |
55 | | - fill="currentColor" |
56 | | - /> |
| 61 | + {left.map((rect) => ( |
| 62 | + <rect |
| 63 | + x={rect.x} |
| 64 | + y={rect.y} |
| 65 | + width={rect.width} |
| 66 | + height={rect.height} |
| 67 | + fill={rect.fill === "fill" ? "var(--v2-icon-icon-muted)" : "currentColor"} |
| 68 | + opacity={rect.fill === "fill" ? 0.72 : rect.fill === "weak" ? 0.2 : 0.12} |
| 69 | + /> |
| 70 | + ))} |
| 71 | + {right.map((rect) => ( |
| 72 | + <rect |
| 73 | + x={rect.x} |
| 74 | + y={rect.y} |
| 75 | + width={rect.width} |
| 76 | + height={rect.height} |
| 77 | + fill="currentColor" |
| 78 | + opacity={rect.fill === "fill" ? 0.72 : rect.fill === "weak" ? 0.2 : 0.12} |
| 79 | + /> |
| 80 | + ))} |
57 | 81 | </g> |
58 | 82 | <defs> |
59 | | - <mask id={mask} maskUnits="userSpaceOnUse" x="0" y="0" width="720" height="129"> |
60 | | - <rect width="720" height="129" fill={`url(#${maskGradient})`} /> |
| 83 | + <mask id={mask} maskUnits="userSpaceOnUse" x="0" y="0" width={width} height={height}> |
| 84 | + <rect width={width} height={height} fill={`url(#${maskGradient})`} /> |
61 | 85 | </mask> |
62 | | - <linearGradient id={maskGradient} x1="360" y1="0" x2="360" y2="112" gradientUnits="userSpaceOnUse"> |
| 86 | + <linearGradient id={maskGradient} x1={width / 2} y1="0" x2={width / 2} y2={height} gradientUnits="userSpaceOnUse"> |
63 | 87 | <stop stop-color="white" stop-opacity="0.7" /> |
64 | 88 | <stop offset="1" stop-color="white" stop-opacity="0" /> |
65 | 89 | </linearGradient> |
66 | 90 | <filter |
67 | 91 | id={filter} |
68 | 92 | x="0" |
69 | 93 | y="0" |
70 | | - width="720.002" |
71 | | - height="130.001" |
| 94 | + width={width} |
| 95 | + height={height} |
72 | 96 | filterUnits="userSpaceOnUse" |
73 | 97 | color-interpolation-filters="sRGB" |
74 | 98 | > |
|
0 commit comments