1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| import './App.css' import {useEffect, useRef} from "react"; import {Button} from 'antd'
function App() { const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
}, []);
function getRandomCoordinateAround(n: number, range: number) { const min = n - range; const max = n + range; return Math.floor(Math.random() * (max - min + 1)) + min; }
function createParticles(imageData:ImageData) { const particles = []; const data = imageData.data; const width = imageData.width; const height = imageData.height;
for (let y = 0; y < height; y += 1) { for (let x = 0; x < width; x += 1) { const index = (x + y * width) * 4; const r = data[index]; const g = data[index + 1]; const b = data[index + 2]; const a = data[index + 3];
particles.push({ x: getRandomCoordinateAround(x, 200), y: getRandomCoordinateAround(y, 200), targetX: x, targetY: y, color: `rgba(${r},${g},${b},${a / 255})` }); } } return particles; }
function animateParticles(particles: any) { const ctx = canvasRef?.current?.getContext('2d') as CanvasRenderingContext2D;
function updateAndDraw() { ctx.clearRect(0, 0, 300, 300);
let allParticlesReachedTarget = true;
particles.forEach((p: any) => { if (p.x < p.targetX) { if (p.targetX - p.x > 5) { p.x += 4; } p.x += 1 allParticlesReachedTarget = false; } if (p.y < p.targetY) { if (p.targetY - p.y > 5) { p.y += 4; } p.y += 1 allParticlesReachedTarget = false; } if (p.x > p.targetX) { if (p.x - p.targetX > 5) { p.x -= 4; } p.x -= 1 allParticlesReachedTarget = false; } if (p.y > p.targetY) { if (p.y - p.targetY > 5) { p.y -= 4; } p.y -= 1 allParticlesReachedTarget = false; }
ctx.fillStyle = p.color; ctx.fillRect(p.x, p.y, 2, 2); });
if (allParticlesReachedTarget) { console.log('动画完成') } else { requestAnimationFrame(updateAndDraw); } } requestAnimationFrame(updateAndDraw); }
const show = () => { const image = new Image() image.src = 'src/assets/images/avatar.png' image.onload = () => { const tempCanvas = document.createElement('canvas'); const tempCtx = tempCanvas.getContext('2d'); tempCanvas.width = 300; tempCanvas.height = 300; tempCtx?.drawImage(image, 0, 0, 300, 300); const imgData = tempCtx?.getImageData(0, 0, 300, 300) as ImageData;
const particles = createParticles(imgData) animateParticles(particles); } } return ( <> <div> <canvas ref={canvasRef} id="canvas" width={300} height={300}></canvas> <div> <Button onClick={show}>显示</Button> </div> </div> </> ) }
export default App
|