canvas线条跟随引力绘图动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas线条跟随引力绘图动画效果代码,小球越大引力越大,线条就会朝它过去。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { height: 100vh; margin: 0; overflow: hidden; display: grid; place-items: center; } #frame-count { position: absolute; bottom: 0; right: 0; display: none; } canvas { width: clamp(200px, 80vmin, 600px); height: clamp(200px, 80vmin, 600px); } </style> </head> <body> <canvas></canvas> <div id="frame-count">0</div> <script > const { cos, sin, pow, atan2, min, max, PI: π } = Math; const query = document.querySelector.bind(document); const canvas = query('canvas'); const ctx = canvas.getContext('2d'); const Physics = { G: 6.7 * 10 }; const setup = () => { const width = 600; const height = 600; canvas.width = width; canvas.height = height; ctx.fillStyle = 'white'; ctx.fillRect(0, 0, width, height); return { width, height }; }; const { width, height } = setup(); const Marker = { // Not confident about physics terminology init({ x, y, mass, radius, style, velocity, angle }) { this.x = x; this.y = y; this.mass = mass; this.radius = radius; this.style = style; this.velocity = velocity; this.angle = angle; this.momentX = this.velocity * cos(this.angle); this.momentY = this.velocity * sin(this.angle); this.velocityX = this.momentX; this.velocityY = this.momentY; this.trail = [{ x: this.x, y: this.y }]; }, gravitateTo(attractor) { const force = Physics.G * this.mass * attractor.mass / ( pow(attractor.x - this.x, 2) + pow(attractor.y - this.y, 2)); const angle = atan2(attractor.y - this.y, attractor.x - this.x); this.momentX += force * cos(angle); this.momentY += force * sin(angle); }, tick() { this.momentX *= 0.8; this.momentY *= 0.8; this.velocityX += this.momentX / 100; this.velocityY += this.momentY / 100; this.x += this.velocityX / 100; this.y += this.velocityY / 100; this.trail.push({ x: this.x, y: this.y }); this.momentX = 0; this.momentY = 0; }, draw(ctx) { this.tick(); ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, π * 2); ctx.fillStyle = this.style; ctx.fill(); ctx.beginPath(); for (let i = 0; i < this.trail.length; i++) { ctx.lineTo(this.trail[i].x, this.trail[i].y); } ctx.lineWidth = this.radius; ctx.strokeStyle = this.style; ctx.stroke(); } }; const masses = [{ x: width / 6, y: height / 6, radius: 10, mass: 1000, style: 'slateblue' }, { x: width / 2, y: height / 6, radius: 10, mass: 1000, style: 'slateblue' }, { x: width - width / 6, y: height / 6, radius: 10, mass: 1000, style: 'slateblue' }, { x: width / 6, y: height / 2, radius: 10, mass: 1000, style: 'slateblue' }, { x: width - width / 6, y: height / 2, radius: 10, mass: 1000, style: 'slateblue' }, { x: width / 6, y: height - height / 6, radius: 10, mass: 1000, style: 'slateblue' }, { x: width / 2, y: height - height / 6, radius: 10, mass: 1000, style: 'slateblue' }, { x: width - width / 6, y: height - height / 6, radius: 10, mass: 1000, style: 'slateblue' }]; const cursorMass = { x: width / 4, y: height / 4, radius: 20, mass: 0, style: 't.........完整代码请登录后点击上方下载按钮下载查看
网友评论0