68 lines
1.8 KiB
Plaintext
68 lines
1.8 KiB
Plaintext
|
import React, { useRef, useEffect } from 'react';
|
||
|
|
||
|
const DistortedGrid = () => {
|
||
|
const canvasRef = useRef(null);
|
||
|
|
||
|
useEffect(() => {
|
||
|
const canvas = canvasRef.current;
|
||
|
const ctx = canvas.getContext('2d');
|
||
|
let t = 0;
|
||
|
const w = 400;
|
||
|
const s = 3;
|
||
|
|
||
|
const mag = (x, y) => Math.sqrt(x * x + y * y);
|
||
|
|
||
|
const a = (x, y, t) => {
|
||
|
const k = x / 8 - 25;
|
||
|
const e = y / 8 - 25;
|
||
|
const d = 2 * Math.cos(mag(k, e) / 3 - t);
|
||
|
return [x + d * k, y + d * e];
|
||
|
};
|
||
|
|
||
|
const shuffle = (array) => {
|
||
|
for (let i = array.length - 1; i > 0; i--) {
|
||
|
const j = Math.floor(Math.random() * (i + 1));
|
||
|
[array[i], array[j]] = [array[j], array[i]];
|
||
|
}
|
||
|
return array;
|
||
|
};
|
||
|
|
||
|
const draw = () => {
|
||
|
ctx.fillStyle = 'rgba(6, 6, 6, 0.1)';
|
||
|
ctx.fillRect(0, 0, w, w);
|
||
|
ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
|
||
|
ctx.lineWidth = 0.5;
|
||
|
|
||
|
for (let y = 100; y < 300; y += s) {
|
||
|
for (let x = 100; x < 300; x += s) {
|
||
|
const points = shuffle([
|
||
|
a(x, y, t),
|
||
|
a(x, y + s, t),
|
||
|
a(x + s, y, t)
|
||
|
]);
|
||
|
ctx.beginPath();
|
||
|
ctx.moveTo(points[0][0], points[0][1]);
|
||
|
ctx.lineTo(points[1][0], points[1][1]);
|
||
|
ctx.stroke();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
t += 0.02;
|
||
|
requestAnimationFrame(draw);
|
||
|
};
|
||
|
|
||
|
draw();
|
||
|
}, []);
|
||
|
|
||
|
return (
|
||
|
<div className="flex items-center justify-center min-h-screen bg-gray-900">
|
||
|
<div className="bg-gray-800 p-4 rounded-lg shadow-lg">
|
||
|
<h2 className="text-xl font-bold text-white mb-4 text-center">Distorted Grid Visualization</h2>
|
||
|
<canvas ref={canvasRef} width="400" height="400" className="border border-gray-700"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default DistortedGrid;
|