p5+simplex-noise实现深海不明生物跟随鼠标移动效果代码
代码语言:html
所属分类:动画
代码描述:p5+simplex-noise实现深海不明生物跟随鼠标移动效果代码
代码标签: p5 simplex-noise 深海 生物 跟随 鼠标 移动
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> html, body { overflow: hidden; background: black; } </style> </head> <body > <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/p5.1.4.0.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/simplex-noise.min.js"></script> <script > const hueBase = 60 const hueRange = 160 const segmentCount = 60 const bubbleCount = 500 const segmentLengthBase = 5 const fadeIn = (t, m) => t / m const fadeOut = (t, m) => (m - t) / m const fadeInOut = (t, m) => { let hm = 0.5 * m return abs((t + hm) % m - hm) / hm } const angle = (x1, y1, x2, y2) => atan2(y2 - y1, x2 - x1) let buffer let canvas let ctx let creature let bubbles let center let tick let simplex class AttributeArray { constructor(count, attrs) { this.count = count this.attrs = attrs this.spread = attrs.length this.values = new Float32Array(count * this.spread) } get length() { return this.values.length } set(a, i, normalize = false) { normalize && (i *= this.spread) this.values.set(a, i) } get(i, normalize = false) { normalize && (i *= this.spread) return this.values.slice(i, i + this.spread) } forEach(cb) { let i = 0 let j = 0 for (; i < this.length; i += this.spread, j++) { cb(this.get(i), j, this) } } map(cb) { let i = 0 let j = 0 for (; i < this.length; i += this.spread, j++) { this.set(cb(this.get(i), j, this), i) } } reverseMap(cb) { let i = this.length - this.spread let j = this.count - 1 for (; i >= 0; i -= this.spread, j--) { this.set(cb(this.get(i), j, this), i) } } } class Bubbles extends AttributeArray { constructor(count) { super(count, ['x', 'y', 'vx', 'vy', 's', 'd', 'h', 'l', 'ttl']) this.initPoints() this.repelTarget = null this.repelThreshold = 100 } setRepelTarget(target = null) { this.repelTarget = target } initPoints() { this.map(() => [ random(windowWidth), random(windowHeight), random(-2, 2), random(-4, -1), random(2, 6), random(2, 6), random(180, 240), random(0, 200), random(500, 1000) ]) } reset() { return [ random(windowWidth), random(windowHeight), 0, random(-4, -1), random(2, 6), random(2, 6), random(180, 240), 0, random(500, 1000) ] } drawParticle(x, y, d, h, l, ttl) { const ld = fadeInOut(l, ttl) buffer.stroke(h, 50, 100, 0.5 * ld) buffer.strokeWeight(1 + d * ld) buffer.point(x, y) } update() { this.map(([x, y, vx, vy, s, d, h, l, ttl]) => { const n = simplex.noise3D(x * 0.0015, y * 0.0015, tick * 0.0015) * TAU vx = lerp(vx, cos(n) * s, 0.15) vy = lerp(vy, (sin(n) + 2) * -s, 0.15) if ( this.repelTarget && dist(x, y, ...this.repelTarget) < this.repelThreshold ) { const theta = angle(x, y, ...this.repelTarget) vx = lerp(vx, vx - cos(theta) * s, 0.275) vy = lerp(vy, vy - sin(theta) * s, 0.275) } x = lerp(x, x + vx, 0.125) y = lerp(y, y + vy, 0.125) l++ this.drawParticle(x, y, d, h, l, ttl) if ( l > ttl || x > windowWidth + d || x < -d || y < -d ) { return this.reset() } return [x, y, vx, vy, s, d, h, l, ttl] }) } } class Segments extends AttributeArray { constructor(x, y, segmentNum, baseLength, baseDirection, additionalAttrs = []) { super(segmentNum, ['x1', 'y1', 'x2', 'y2', 'l', 'd', ...additionalAttrs]) this.position = [x, y] this.target = [x, y] this.baseLength = baseLength this.baseDirection = baseDirection } get segmentNum() { return this.count } setTarget(arg) { if (typeof arg === 'function') { this.target = arg(this.target) } else { this.target = arg } } setPosition(arg) { if (typeof arg === 'function') { this.position = arg(this.position) } else { this.position = arg } } mapSegments.........完整代码请登录后点击上方下载按钮下载查看
网友评论0