11'use client' ;
22
3- const hashString = ( value ) => {
4- let hash = 0 ;
5- for ( let i = 0 ; i < value . length ; i += 1 ) {
6- hash = value . charCodeAt ( i ) + ( ( hash << 5 ) - hash ) ;
7- }
8- return hash ;
9- } ;
3+ import { useMemo } from "react" ;
104
11- const mapToRange = ( value , min , max ) => {
12- const normalized = Math . abs ( value % 1000 ) / 1000 ;
13- return min + normalized * ( max - min ) ;
14- } ;
5+ const mapToRange = ( value , min , max ) => min + value * ( max - min ) ;
156
167const defaultColors = {
178 highlight : "text-cblue" ,
@@ -20,28 +11,33 @@ const defaultColors = {
2011} ;
2112
2213export default function GuestbookWordCloud ( { entries, isLoading, recentCount = 5 , className = "" , style = { } , colorScheme = defaultColors } ) {
23- const words = ( entries ?? [ ] ) . map ( ( entry , idx ) => {
24- const key = entry . id ?? `${ entry . wristbandSerial ?? "unknown" } -${ idx } ` ;
25- const baseHash = hashString ( `${ key } -${ entry . name } ` ) ;
26- const top = mapToRange ( baseHash , 12 , 88 ) ;
27- const left = mapToRange ( baseHash * 3 , 10 , 90 ) ;
28- const fontSize = mapToRange ( baseHash * 5 , 1.2 , 3.2 ) ;
29- const rotate = mapToRange ( baseHash * 7 , - 10 , 10 ) ;
30- const opacity = mapToRange ( baseHash * 11 , 0.45 , 0.95 ) ;
14+ const words = useMemo ( ( ) => {
15+ if ( ! entries ?. length ) {
16+ return [ ] ;
17+ }
18+
19+ return entries . map ( ( entry , idx ) => {
20+ const key = entry . id ?? `${ entry . wristbandSerial ?? "unknown" } -${ idx } ` ;
21+ const top = mapToRange ( Math . random ( ) , 12 , 88 ) ;
22+ const left = mapToRange ( Math . random ( ) , 10 , 90 ) ;
23+ const fontSize = mapToRange ( Math . random ( ) , 1.2 , 3.2 ) ;
24+ const rotate = mapToRange ( Math . random ( ) , - 10 , 10 ) ;
25+ const opacity = mapToRange ( Math . random ( ) , 0.45 , 0.95 ) ;
3126
32- return {
33- key,
34- label : entry . name ,
35- isRecent : idx >= Math . max ( entries . length - recentCount , 0 ) ,
36- style : {
37- top : `${ top } %` ,
38- left : `${ left } %` ,
39- fontSize : `${ fontSize } rem` ,
40- opacity,
41- transform : `translate(-50%, -50%) rotate(${ rotate } deg)` ,
42- } ,
43- } ;
44- } ) ;
27+ return {
28+ key,
29+ label : entry . name ,
30+ isRecent : idx >= Math . max ( entries . length - recentCount , 0 ) ,
31+ style : {
32+ top : `${ top } %` ,
33+ left : `${ left } %` ,
34+ fontSize : `${ fontSize } rem` ,
35+ opacity,
36+ transform : `translate(-50%, -50%) rotate(${ rotate } deg)` ,
37+ } ,
38+ } ;
39+ } ) ;
40+ } , [ entries , recentCount ] ) ;
4541
4642 return (
4743 < div className = { `absolute inset-0 pointer-events-none select-none ${ className } ` } style = { style } >
0 commit comments