2.8 KB93 lines
Blame
1"use client";
2
3import { useCallback, useId, useRef } from "react";
4
5interface Props {
6 size?: number;
7}
8
9export function CanopyLogo({ size = 24 }: Props) {
10 const svgRef = useRef<SVGSVGElement>(null);
11 const id = useId();
12 const s = id.replace(/:/g, "");
13
14 const onMouseMove = useCallback((e: React.MouseEvent<SVGSVGElement>) => {
15 const rect = e.currentTarget.getBoundingClientRect();
16 const relX = ((e.clientX - rect.left) / rect.width - 0.5) * 2;
17 e.currentTarget.style.setProperty("--sway", `${relX * 5}deg`);
18 }, []);
19
20 const onMouseLeave = useCallback((e: React.MouseEvent<SVGSVGElement>) => {
21 e.currentTarget.style.setProperty("--sway", "0deg");
22 }, []);
23
24 return (
25 <svg
26 ref={svgRef}
27 className={`canopy-logo-${s}`}
28 width={size}
29 height={size}
30 viewBox="0 0 64 64"
31 fill="none"
32 onMouseMove={onMouseMove}
33 onMouseLeave={onMouseLeave}
34 >
35 <style>{`
36 .canopy-logo-${s} {
37 cursor: pointer;
38 transition: transform 0.5s cubic-bezier(0.25, 1, 0.5, 1);
39 }
40 .canopy-logo-${s}:hover,
41 .hover-row:hover .canopy-logo-${s} {
42 }
43 .canopy-logo-${s} .cl-bg {
44 transition: filter 0.6s ease;
45 }
46 .canopy-logo-${s}:hover .cl-bg,
47 .hover-row:hover .canopy-logo-${s} .cl-bg {
48 filter: brightness(0.9);
49 }
50 .canopy-logo-${s} .cl-canopy {
51 transform-origin: 31px 42px;
52 transform: rotate(var(--sway, 0deg));
53 transition: transform 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
54 }
55 .canopy-logo-${s}:hover .cl-canopy,
56 .hover-row:hover .canopy-logo-${s} .cl-canopy {
57 transition: transform 0.15s ease-out;
58 }
59 .canopy-logo-${s} .cl-trunk {
60 transition: stroke-width 0.4s cubic-bezier(0.25, 1, 0.5, 1);
61 }
62 .canopy-logo-${s}:hover .cl-trunk,
63 .hover-row:hover .canopy-logo-${s} .cl-trunk {
64 stroke-width: 3.2;
65 }
66 .canopy-logo-${s} .cl-root {
67 transition: stroke-width 0.4s cubic-bezier(0.25, 1, 0.5, 1) 0.05s;
68 }
69 .canopy-logo-${s}:hover .cl-root,
70 .hover-row:hover .canopy-logo-${s} .cl-root {
71 stroke-width: 2.2;
72 }
73 `}</style>
74
75 <circle cx="32" cy="32" r="32" fill="var(--accent)" className="cl-bg" />
76 <g className="cl-canopy">
77 <path className="cl-trunk" d="M31 42 L30 53" stroke="white" strokeWidth="2.5" strokeLinecap="round"/>
78 <path className="cl-root" d="M30.5 46 L34 49.5" stroke="white" strokeWidth="1.5" strokeLinecap="round"/>
79 <path d="
80 M31 42
81 C18 40, 11 32, 14 24
82 C16 17, 24 12, 31 14
83 C33 10, 40 12, 43 16
84 C48 14, 52 22, 49 28
85 C52 34, 46 40, 38 40
86 C36 42, 33 43, 31 42
87 Z
88 " fill="white"/>
89 </g>
90 </svg>
91 );
92}
93