canvas实现水母游动可交互跟随鼠标动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas实现水母游动可交互跟随鼠标动画效果代码
代码标签: canvas 水母 游动 交互 跟随 鼠标 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> html, body { width: 100%; height: 100%; margin: 0; background: rgb(0,30,60); overflow: hidden; } #C{ } </style> </head> <body> <!-- partial:index.partial.html --> <canvas id="C"></canvas> <!-- partial --> <script > window.onload = function () { let ctx = document.getElementById("C"), c = ctx.getContext("2d"), w, h; fitCanvas(); function limit(vec, b) { this.d = Math.sqrt(Math.pow(vec.x, 2) + Math.pow(vec.y, 2)); this.ang = Math.atan2(vec.y, vec.x); if (this.d > b) { return { x: b * Math.cos(this.ang), y: b * Math.sin(this.ang) }; } else { return { x: this.d * Math.cos(this.ang), y: this.d * Math.sin(this.ang) }; } } function setmag(a, m) { this.ang = Math.atan2(a.y, a.x); return { x: m * Math.cos(this.ang), y: m * Math.sin(this.ang) }; } let mouse = { x: false, y: false }, last_mouse = {}, pi = Math.PI, seaMargin = 1000, boids = new Array(100); class boid { constructor() { this.opacity = Math.random() * 0.5 + 0.05; this.ang = Math.random() * 2 * Math.PI; this.mf = 0.1; this.ms = Math.random() * 0.1 + 0.9; this.vm = Math.random() * 1 + 0.5; this.pos = { x: Math.random() * w, y: Math.random() * h }; this.vel = { x: this.vm * Math.cos(this.ang), y: this.vm * Math.sin(this.ang) }; this.acc = { x: 0, y: 0 }; } flock(other) { this.aa = { x: 0, y: 0 }; this.ap = { x: 0, y: 0 }; this.as = { x: 0, y: 0 }; this.count = 0; for (var ot of other) { if (ot != this) { this.dis = Math.sqrt( Math.pow(ot.pos.x - this.pos.x, 2) + Math.pow(ot.pos.y - this.pos.y, 2) ); if (this.dis < 40) { this.aa.x += ot.vel.x; this.aa.y += ot.vel.y; this.ap.x += ot.pos.x; this.ap.y += ot.pos.y; this.as.x += this.pos.x - ot.pos.x; this.as.y += this.pos.y - ot.pos.y; this.count++; } } } if (this.count != 0) { this.aa.x /= this.count; this.aa.y /= this.count; this.ap.x /= this.count; this.ap.y /= this.count; this.as.x /= this.count; this.as.y /= this.count; this.as = setmag( this.as, 4 / Math.sqrt(Math.pow(this.as.x, 2) + Math.pow(this.as.y, 2)) ); this.aa.x -= this.vel.x; this.aa.y -= this.vel.y; this.ap.x -= this.vel.x; this.ap.y -= this.vel.y; } this.aa = limit(this.aa, this.mf); this.ap = limit(this.ap, this.mf); this.as = limit(this.as, 4 * this.mf); } move() { this.acc = { x: 0, y: 0 }; this.acc.x += this.aa.x; this.acc.y += this.aa.y; this.acc.x += this.ap.x; this.acc.y += this.ap.y; this.acc.x += this.as.x; this.acc.y += this.as.y; this.pos.x += this.vel.x; this.pos.y += this.vel.y; this.vel.x += this.acc.x; this.vel.y += this.acc.y; this.vel = limit(this.vel, this.ms); this.ang = Math.atan2(this.vel.y, this.vel.x); if (this.pos.x > w + seaMargin) { this.pos.x -= w + seaMargin; } if (this.pos.x < -seaMargin) { this.pos.x += w + seaMargin; } if (this.pos.y > h + seaMargin) { this.pos.y -= h + seaMargin; } if (this.pos.y < -seaMargin) { this.pos.y += h + seaMargin; } } show() { c.beginPath(); c.lineTo( this.pos.x - this.opacity * 20 * Math.cos(this.ang), this.pos.y - this.opacity * 20 * Math.sin(this.ang) ); c.lineTo( this.pos.x + this.opacity * 20 * Math.cos(this.ang), this.pos.y + this.opacity * 20 * Math.sin(this.ang) ); c.strokeStyle = "rgba(255,255,255," + this.opacity + ")"; c.lineWidth = this.opacity * 8; c.lineCap = "round"; c.stroke(); } } class node { constructor(x, y, size, index, length) { this.x = x; this.y = y; this.size = size; this.angle = Math.random() * 2 * Math.PI; this.nx = this.x + size * 2 * Math.cos(this.angle); this.ny = this.y + size * 2 * Math.sin(this.angle); this.i = index; this.l = length; } follow(m) { this.errx = m.x - this.x; this.erry = m.y - this.y; this.td = Math.sqrt(Math.pow(this.errx, 2) + Math.pow(this.erry, 2)); this.ta = Math.atan2(this.erry, this.errx); this.x = this.x + this.td * 0.2 * Math.cos(this.ta); this.y = this.y + this.td * 0.2 * Math.sin(this.ta); } update(other, r) { this.errx = other.x - this.x; this.erry = other.y - this.y; this.a = Math.atan2(this.erry, this.errx); this.nx = this.x + r * Math.cos(this.a); this.ny = this.y + r * Math.sin(this.a); } avoid(other, rad) { this.d = Math.sqrt( Math.pow(other.x - this.x, 2) + Math.pow(other.y - this.y, 2) ); this.ang = Math.atan2.........完整代码请登录后点击上方下载按钮下载查看
网友评论0