Mercurial
comparison hg-web/src/components/graph.tsx @ 194:fb28063dc490 hg-web
Adding few more images.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 25 Jan 2026 20:19:42 -0800 |
| parents | 9f4429c49733 |
| children |
comparison
equal
deleted
inserted
replaced
| 193:9f4429c49733 | 194:fb28063dc490 |
|---|---|
| 181 const changesets = useMemo(() => | 181 const changesets = useMemo(() => |
| 182 maxRows && data?.changesets ? data.changesets.slice(0, maxRows) : data?.changesets || [], [data, maxRows]); | 182 maxRows && data?.changesets ? data.changesets.slice(0, maxRows) : data?.changesets || [], [data, maxRows]); |
| 183 | 183 |
| 184 let pencilPattern; | 184 let pencilPattern; |
| 185 const img = new Image(); | 185 const img = new Image(); |
| 186 img.src = "http://localhost:6970/pencil_texture.png"; | 186 img.src = "http://localhost:6970/pencil_lines.png"; |
| 187 | |
| 188 const pandaImg = new Image(); | |
| 189 pandaImg.src = "http://localhost:6970/panda.png"; | |
| 187 | 190 |
| 188 useEffect(() => { | 191 useEffect(() => { |
| 189 const canvas = canvasRef.current; | 192 const canvas = canvasRef.current; |
| 190 if (!canvas || !changesets.length) return; | 193 if (!canvas || !changesets.length) return; |
| 191 | 194 |
| 236 }); | 239 }); |
| 237 | 240 |
| 238 // Pass 2: Draw Commit Nodes | 241 // Pass 2: Draw Commit Nodes |
| 239 changesets.forEach((cs, i) => { | 242 changesets.forEach((cs, i) => { |
| 240 const x = getX(cs.col), y = getY(i); | 243 const x = getX(cs.col), y = getY(i); |
| 241 const color = colors[cs.color % colors.length]; | 244 ctx.drawImage(pandaImg, x-10, y-10, 20, 20); |
| 242 | |
| 243 // Sketchy outer glow | |
| 244 ctx.beginPath(); | |
| 245 ctx.arc(x, y, nodeRadius + 2, 0, Math.PI * 2); | |
| 246 ctx.fillStyle = `${color}33`; | |
| 247 ctx.fill(); | |
| 248 | |
| 249 // Core Node | |
| 250 ctx.beginPath(); | |
| 251 ctx.arc(x, y, nodeRadius, 0, Math.PI * 2); | |
| 252 ctx.fillStyle = color; | |
| 253 ctx.fill(); | |
| 254 | |
| 255 // Sketchy border rings | |
| 256 for (let s = 0; s < 2; s++) { | |
| 257 ctx.beginPath(); | |
| 258 ctx.arc(x + (Math.random() - 0.5), y + (Math.random() - 0.5), nodeRadius + 0.5, 0, Math.PI * 2); | |
| 259 ctx.strokeStyle = '#000000'; | |
| 260 ctx.globalAlpha = 0.3; | |
| 261 ctx.lineWidth = 0.8; | |
| 262 ctx.stroke(); | |
| 263 } | |
| 264 ctx.globalAlpha = 1; | |
| 265 }); | 245 }); |
| 266 }; | 246 }; |
| 267 | 247 |
| 268 img.onload = () => { | 248 img.onload = () => { |
| 269 console.log("WTF"); | |
| 270 pencilPattern = ctx.createPattern(img, "repeat")!; | 249 pencilPattern = ctx.createPattern(img, "repeat")!; |
| 271 renderCanvas(); | 250 renderCanvas(); |
| 272 }; | 251 }; |
| 273 }, [changesets]); | 252 }, [changesets]); |
| 274 | 253 |
| 285 if (sentinel) observer.observe(sentinel); | 264 if (sentinel) observer.observe(sentinel); |
| 286 return () => observer.disconnect(); | 265 return () => observer.disconnect(); |
| 287 }, [onLoadMore, hasMore, loading]); | 266 }, [onLoadMore, hasMore, loading]); |
| 288 | 267 |
| 289 return ( | 268 return ( |
| 290 <div style={{ display: 'flex', flexDirection: 'column', height: '100%', background: '#1a1a1a', fontFamily: 'monospace' }}> | 269 <div style={{ display: 'flex', flexDirection: 'column', height: '100%', backgroundImage: 'url("/hg-web-background.jpg")', fontFamily: 'monospace' }}> |
| 291 <div | 270 <div |
| 292 ref={containerRef} | 271 ref={containerRef} |
| 293 style={{ display: 'flex', flex: 1, overflowY: 'auto', position: 'relative' }} | 272 style={{ display: 'flex', flex: 1, overflowY: 'auto', position: 'relative' }} |
| 294 > | 273 > |
| 295 {/* Graph Column - Sticky to keep lines aligned with text during scroll */} | 274 {/* Graph Column - Sticky to keep lines aligned with text during scroll */} |