2 喜欢

【Canvas动画】文本粒子效果

admin
admin
2021-10-17 23:39:23 阅读 1135

在线演示

See the Pen Canvas Particle Demo by pdslly (@pdslly) on CodePen.

参考代码

const mycan = document.getElementById("mycan"); const ctx = mycan.getContext("2d"); const { clientLeft, clientTop } = mycan; let { innerWidth, innerHeight } = window; let adjustX = innerWidth / 100; let adjustY = innerHeight / 200; mycan.width = innerWidth; mycan.height = innerHeight; ctx.font = "bold 20px Verdana"; ctx.fillText("IFRONT", 0, 30); const data = ctx.getImageData(0, 0, mycan.width, 100); let particleArray = []; const mouse = { x: null, y: null, radius: 150, }; window.addEventListener("mousemove", function ({ x, y }) { mouse.x = x + clientLeft; mouse.y = y + clientTop; }); class Particle { constructor(x, y) { this.x = this.baseX = x; this.y = this.baseY = y; this.size = 3; this.density = Math.random() * 30 + 1; } draw() { const { x, y, size } = this; ctx.fillStyle = "white"; ctx.beginPath(); ctx.arc(x, y, size, 0, Math.PI * 2); ctx.closePath(); ctx.fill(); } update() { const { x, y, size, density, baseX, baseY } = this; const { x: mx, y: my, radius } = mouse; const dx = mx - x; const dy = my - y; const distance = Math.sqrt(dx * dx + dy * dy); const forceDirX = dx / distance; const forceDirY = dy / distance; const force = Math.max(0, (radius - distance) / radius); if (distance < size + radius) { const dirX = forceDirX * force * density; const dirY = forceDirY * force * density; this.x -= dirX; this.y -= dirY; } else { if (x !== baseX) { this.x -= (x - baseX) / 10; } if (y !== baseY) { this.y -= (y - baseY) / 10; } } } } function init() { particleArray = []; for (let x = 0, w = data.width; x < w; x++) { for (let y = 0, h = data.height; y < h; y++) { if (data.data[y * 4 * w + x * 4 + 3] > 128) { let posX = x + adjustX; let posY = y + adjustY; particleArray.push(new Particle(posX * 15, posY * 15)); } } } } function animate() { ctx.clearRect(0, 0, innerWidth, innerHeight); connect(); for (const particle of particleArray) { particle.update(); particle.draw(); } requestAnimationFrame(animate); } function connect() { const len = particleArray.length; for (let a = 0; a < len; a++) { for (let b = 0; b < len; b++) { const C_DISTANCE = 2500; let { x: ax, y: ay } = particleArray[a]; let { x: bx, y: by } = particleArray[b]; let opacityValue = 1; let weight = 255; let disX = ax - bx; let disY = ay - by; let distance = disX * disX + disY * disY; let { x: mx, y: my, radius } = mouse; if (distance < C_DISTANCE) { opacityValue = 1 - distance / C_DISTANCE; let dx = mx - ax; let dy = my - ay; let mDis = Math.sqrt(dx * dx + dy * dy); if (mDis < radius / 2) weight = 0; else if (mDis < radius - 50) weight = 140; else if (mDis < radius + 20) weight = 210; ctx.strokeStyle = `rgba(255,255,${weight},${opacityValue})`; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(ax, ay); ctx.lineTo(bx, by); ctx.stroke(); } } } } window.addEventListener("resize", function () { let { innerWidth, innerHeight } = window; mycan.width = innerWidth; mycan.height = innerHeight; adjustX = innerWidth / 200; adjustY = innerHeight / 200; ctx.clearRect(0, 0, innerWidth, innerHeight); init(); }); init(); animate();

关于作者
admin
admin
admin@ifront.net
 获得点赞 173
 文章阅读量 172501
文章标签