Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/www/public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6654,8 +6654,8 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
canvas.height = height * dpr
canvas.style.width = `${width}px`
canvas.style.height = `${height}px`
const cols = Math.floor(width / (squareSize + gridGap))
const rows = Math.floor(height / (squareSize + gridGap))
const cols = Math.ceil(width / (squareSize + gridGap))
const rows = Math.ceil(height / (squareSize + gridGap))

const squares = new Float32Array(cols * rows)
for (let i = 0; i < squares.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/r/flickering-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"files": [
{
"path": "registry/magicui/flickering-grid.tsx",
"content": "\"use client\"\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ninterface FlickeringGridProps extends React.HTMLAttributes<HTMLDivElement> {\n squareSize?: number\n gridGap?: number\n flickerChance?: number\n color?: string\n width?: number\n height?: number\n className?: string\n maxOpacity?: number\n}\n\nexport const FlickeringGrid: React.FC<FlickeringGridProps> = ({\n squareSize = 4,\n gridGap = 6,\n flickerChance = 0.3,\n color = \"rgb(0, 0, 0)\",\n width,\n height,\n className,\n maxOpacity = 0.3,\n ...props\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [isInView, setIsInView] = useState(false)\n const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 })\n\n const memoizedColor = useMemo(() => {\n const toRGBA = (color: string) => {\n if (typeof window === \"undefined\") {\n return `rgba(0, 0, 0,`\n }\n const canvas = document.createElement(\"canvas\")\n canvas.width = canvas.height = 1\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return \"rgba(255, 0, 0,\"\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data)\n return `rgba(${r}, ${g}, ${b},`\n }\n return toRGBA(color)\n }, [color])\n\n const setupCanvas = useCallback(\n (canvas: HTMLCanvasElement, width: number, height: number) => {\n const dpr = window.devicePixelRatio || 1\n canvas.width = width * dpr\n canvas.height = height * dpr\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n const cols = Math.floor(width / (squareSize + gridGap))\n const rows = Math.floor(height / (squareSize + gridGap))\n\n const squares = new Float32Array(cols * rows)\n for (let i = 0; i < squares.length; i++) {\n squares[i] = Math.random() * maxOpacity\n }\n\n return { cols, rows, squares, dpr }\n },\n [squareSize, gridGap, maxOpacity]\n )\n\n const updateSquares = useCallback(\n (squares: Float32Array, deltaTime: number) => {\n for (let i = 0; i < squares.length; i++) {\n if (Math.random() < flickerChance * deltaTime) {\n squares[i] = Math.random() * maxOpacity\n }\n }\n },\n [flickerChance, maxOpacity]\n )\n\n const drawGrid = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n cols: number,\n rows: number,\n squares: Float32Array,\n dpr: number\n ) => {\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = \"transparent\"\n ctx.fillRect(0, 0, width, height)\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n const opacity = squares[i * rows + j]\n ctx.fillStyle = `${memoizedColor}${opacity})`\n ctx.fillRect(\n i * (squareSize + gridGap) * dpr,\n j * (squareSize + gridGap) * dpr,\n squareSize * dpr,\n squareSize * dpr\n )\n }\n }\n },\n [memoizedColor, squareSize, gridGap]\n )\n\n useEffect(() => {\n const canvas = canvasRef.current\n const container = containerRef.current\n if (!canvas || !container) return\n\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n let animationFrameId: number\n let gridParams: ReturnType<typeof setupCanvas>\n\n const updateCanvasSize = () => {\n const newWidth = width || container.clientWidth\n const newHeight = height || container.clientHeight\n setCanvasSize({ width: newWidth, height: newHeight })\n gridParams = setupCanvas(canvas, newWidth, newHeight)\n }\n\n updateCanvasSize()\n\n let lastTime = 0\n const animate = (time: number) => {\n if (!isInView) return\n\n const deltaTime = (time - lastTime) / 1000\n lastTime = time\n\n updateSquares(gridParams.squares, deltaTime)\n drawGrid(\n ctx,\n canvas.width,\n canvas.height,\n gridParams.cols,\n gridParams.rows,\n gridParams.squares,\n gridParams.dpr\n )\n animationFrameId = requestAnimationFrame(animate)\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateCanvasSize()\n })\n\n resizeObserver.observe(container)\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n setIsInView(entry.isIntersecting)\n },\n { threshold: 0 }\n )\n\n intersectionObserver.observe(canvas)\n\n if (isInView) {\n animationFrameId = requestAnimationFrame(animate)\n }\n\n return () => {\n cancelAnimationFrame(animationFrameId)\n resizeObserver.disconnect()\n intersectionObserver.disconnect()\n }\n }, [setupCanvas, updateSquares, drawGrid, width, height, isInView])\n\n return (\n <div\n ref={containerRef}\n className={cn(`h-full w-full ${className}`)}\n {...props}\n >\n <canvas\n ref={canvasRef}\n className=\"pointer-events-none\"\n style={{\n width: canvasSize.width,\n height: canvasSize.height,\n }}\n />\n </div>\n )\n}\n",
"content": "\"use client\"\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ninterface FlickeringGridProps extends React.HTMLAttributes<HTMLDivElement> {\n squareSize?: number\n gridGap?: number\n flickerChance?: number\n color?: string\n width?: number\n height?: number\n className?: string\n maxOpacity?: number\n}\n\nexport const FlickeringGrid: React.FC<FlickeringGridProps> = ({\n squareSize = 4,\n gridGap = 6,\n flickerChance = 0.3,\n color = \"rgb(0, 0, 0)\",\n width,\n height,\n className,\n maxOpacity = 0.3,\n ...props\n}) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [isInView, setIsInView] = useState(false)\n const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 })\n\n const memoizedColor = useMemo(() => {\n const toRGBA = (color: string) => {\n if (typeof window === \"undefined\") {\n return `rgba(0, 0, 0,`\n }\n const canvas = document.createElement(\"canvas\")\n canvas.width = canvas.height = 1\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return \"rgba(255, 0, 0,\"\n ctx.fillStyle = color\n ctx.fillRect(0, 0, 1, 1)\n const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data)\n return `rgba(${r}, ${g}, ${b},`\n }\n return toRGBA(color)\n }, [color])\n\n const setupCanvas = useCallback(\n (canvas: HTMLCanvasElement, width: number, height: number) => {\n const dpr = window.devicePixelRatio || 1\n canvas.width = width * dpr\n canvas.height = height * dpr\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n const cols = Math.ceil(width / (squareSize + gridGap))\n const rows = Math.ceil(height / (squareSize + gridGap))\n\n const squares = new Float32Array(cols * rows)\n for (let i = 0; i < squares.length; i++) {\n squares[i] = Math.random() * maxOpacity\n }\n\n return { cols, rows, squares, dpr }\n },\n [squareSize, gridGap, maxOpacity]\n )\n\n const updateSquares = useCallback(\n (squares: Float32Array, deltaTime: number) => {\n for (let i = 0; i < squares.length; i++) {\n if (Math.random() < flickerChance * deltaTime) {\n squares[i] = Math.random() * maxOpacity\n }\n }\n },\n [flickerChance, maxOpacity]\n )\n\n const drawGrid = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n cols: number,\n rows: number,\n squares: Float32Array,\n dpr: number\n ) => {\n ctx.clearRect(0, 0, width, height)\n ctx.fillStyle = \"transparent\"\n ctx.fillRect(0, 0, width, height)\n\n for (let i = 0; i < cols; i++) {\n for (let j = 0; j < rows; j++) {\n const opacity = squares[i * rows + j]\n ctx.fillStyle = `${memoizedColor}${opacity})`\n ctx.fillRect(\n i * (squareSize + gridGap) * dpr,\n j * (squareSize + gridGap) * dpr,\n squareSize * dpr,\n squareSize * dpr\n )\n }\n }\n },\n [memoizedColor, squareSize, gridGap]\n )\n\n useEffect(() => {\n const canvas = canvasRef.current\n const container = containerRef.current\n if (!canvas || !container) return\n\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n let animationFrameId: number\n let gridParams: ReturnType<typeof setupCanvas>\n\n const updateCanvasSize = () => {\n const newWidth = width || container.clientWidth\n const newHeight = height || container.clientHeight\n setCanvasSize({ width: newWidth, height: newHeight })\n gridParams = setupCanvas(canvas, newWidth, newHeight)\n }\n\n updateCanvasSize()\n\n let lastTime = 0\n const animate = (time: number) => {\n if (!isInView) return\n\n const deltaTime = (time - lastTime) / 1000\n lastTime = time\n\n updateSquares(gridParams.squares, deltaTime)\n drawGrid(\n ctx,\n canvas.width,\n canvas.height,\n gridParams.cols,\n gridParams.rows,\n gridParams.squares,\n gridParams.dpr\n )\n animationFrameId = requestAnimationFrame(animate)\n }\n\n const resizeObserver = new ResizeObserver(() => {\n updateCanvasSize()\n })\n\n resizeObserver.observe(container)\n\n const intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n setIsInView(entry.isIntersecting)\n },\n { threshold: 0 }\n )\n\n intersectionObserver.observe(canvas)\n\n if (isInView) {\n animationFrameId = requestAnimationFrame(animate)\n }\n\n return () => {\n cancelAnimationFrame(animationFrameId)\n resizeObserver.disconnect()\n intersectionObserver.disconnect()\n }\n }, [setupCanvas, updateSquares, drawGrid, width, height, isInView])\n\n return (\n <div\n ref={containerRef}\n className={cn(`h-full w-full ${className}`)}\n {...props}\n >\n <canvas\n ref={canvasRef}\n className=\"pointer-events-none\"\n style={{\n width: canvasSize.width,\n height: canvasSize.height,\n }}\n />\n </div>\n )\n}\n",
"type": "registry:ui"
}
]
Expand Down
4 changes: 2 additions & 2 deletions apps/www/registry/magicui/flickering-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ export const FlickeringGrid: React.FC<FlickeringGridProps> = ({
canvas.height = height * dpr
canvas.style.width = `${width}px`
canvas.style.height = `${height}px`
const cols = Math.floor(width / (squareSize + gridGap))
const rows = Math.floor(height / (squareSize + gridGap))
const cols = Math.ceil(width / (squareSize + gridGap))
const rows = Math.ceil(height / (squareSize + gridGap))

const squares = new Float32Array(cols * rows)
for (let i = 0; i < squares.length; i++) {
Expand Down