This repository has no description
1import React, { useEffect, useRef } from 'react';
2
3const CircularLogo = ({
4 did = "did:plc:gq4fo3u6tqzzdkjlwzpb23tj",
5 logoSrc = "/credbluebadge.png",
6 size = 250,
7 textGap = 10,
8 fontSize = 21,
9 viewBoxPadding = 20,
10 gapDegrees = 3, // Gap in degrees between text start/end
11 webDidRepetitions = 2 // Number of times to repeat did:web text
12}) => {
13 // Determine if it's a web DID and create repeated text if necessary
14 const isWebDid = did.startsWith('did:web');
15 const text = isWebDid
16 ? Array(webDidRepetitions).fill(did).join(' ')
17 : did;
18
19 const textGroupRef = useRef(null);
20
21 // Calculate dimensions based on content
22 const logoSize = size * 0.4;
23 const textRadius = (logoSize / 2) + textGap;
24 const contentSize = (textRadius + fontSize) * 2;
25 const viewBoxSize = contentSize + (viewBoxPadding * 2);
26 const center = viewBoxSize / 2;
27
28 // Calculate circumference and text length
29 const circumference = 2 * Math.PI * textRadius;
30 const gapSize = (gapDegrees / 360) * circumference; // Size of gap in pixels
31 const textLength = circumference - gapSize; // Available space for text
32
33 useEffect(() => {
34 if (textGroupRef.current) {
35 let rotation = 0;
36 let animationFrameId;
37
38 const animate = () => {
39 rotation = (rotation - 0.2) % 360;
40 if (textGroupRef.current) {
41 textGroupRef.current.style.transform = `rotate(${rotation}deg)`;
42 }
43 animationFrameId = requestAnimationFrame(animate);
44 };
45
46 animate();
47
48 return () => {
49 if (animationFrameId) {
50 cancelAnimationFrame(animationFrameId);
51 }
52 };
53 }
54 }, []);
55
56 return (
57 <div className="circular-badge">
58 <svg
59 width={viewBoxSize}
60 height={viewBoxSize}
61 viewBox={`0 0 ${viewBoxSize} ${viewBoxSize}`}
62 className="relative"
63 >
64 {/* Group for rotating text */}
65 <g ref={textGroupRef} style={{ transformOrigin: 'center' }}>
66 <defs>
67 <path
68 id="circlePath"
69 d={`
70 M ${center}, ${center - textRadius}
71 a ${textRadius},${textRadius} 0 1,1 0,${textRadius * 2}
72 a ${textRadius},${textRadius} 0 1,1 0,-${textRadius * 2}
73 `}
74 fill="none"
75 />
76 </defs>
77 <text className="circular-logo-text" fontSize={fontSize}>
78 <textPath
79 href="#circlePath"
80 spacing="auto"
81 startOffset={`${(gapDegrees / 2)}%`}
82 textLength={textLength}
83 lengthAdjust="spacing"
84 >
85 {text}
86 </textPath>
87 </text>
88 </g>
89
90 {/* Center circle for logo - outside the rotating group */}
91 <image
92 x={center - (logoSize / 2)}
93 y={center - (logoSize / 2)}
94 width={logoSize}
95 height={logoSize}
96 href={logoSrc}
97 className="rounded-full"
98 />
99 </svg>
100 </div>
101 );
102};
103
104export default CircularLogo;