生长自由js动画效果
代码语言:html
所属分类:动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> Freedom 4</title> <style> body { background: black; } canvas.drawer { position:fixed; top: 0px; left: 0px; width: 100vw; height: 100vh; } </style> </head> <body translate="no"> <script> // Liam Egan // 2019 let initialise = function () { let application = new Application(); // application.scaleFactor = 2; // application.clearOnRedraw = Application.FADE; application.fadeColour = 'rgba(0,0,0,.12)'; application.fillColour = 'rgba(30,30,30,1)'; application.onResize(); let vfield = new VectorField(); vfield.scale = 2000; vfield.amplitude = 10; // vfield.debug = true; application.addActor(vfield); let maxNum = 1000; let num = 0; let addTracer = (position, colour) => { if (num > maxNum) return; let tracer = new BranchTracer(position.x, position.y); tracer.field = vfield; let momentum = new Vector(Math.random(), Math.random()); momentum.length = Math.random() * 2; tracer.momentum = momentum; tracer.friction = 0.97; if (colour) { tracer.colour = colour; } else { tracer.colour = 'RGBA(' + 100 + Math.round(Math.random() * 155) + ',' + 100 + Math.round(Math.random() * 155) + ',255,0.5)'; } application.addActor(tracer); num = application.actors.length; return tracer; }; let seed = addTracer(new Vector(window.innerWidth / 2, window.innerHeight / 2), 'RGBA(255, 100, 100, 0.5)'); seed.initial = true; seed.branchChance = 15; seed.friction = 0.9975; seed.onBranch = addTracer; // setInterval(()=> { // vfield.z = Math.random() * 10000; // }, 10000) let stage = application.stage; document.body.appendChild(stage); application.onPointerMove({ clientX: window.innerWidth / 2, clientY: window.innerHeight / 2 }); application.render(); application.animating = true; // application.runFor(60 * 120); return; }; class Application { constructor() { this.stage = document.createElement('canvas'); this.animate = this.animate.bind(this); this.onResize = this.onResize.bind(this); this.onPointerDown = this.onPointerDown.bind(this); this.onPointerup = this.onPointerup.bind(this); this.onPointerMove = this.onPointerMove.bind(this); this.initialiseEvents(); } initialiseEvents() { window.addEventListener('resize', this.onResize, false); document.addEventListener('pointerdown', this.onPointerDown, false); document.addEventListener('pointerup', this.onPointerup, false); document.addEventListener('pointermove', this.onPointerMove, false); } deInitialiseEvents() { window.removeEventListener('resize', this.onResize, false); document.removeEventListener('pointerdown', this.onPointerDown, false); document.removeEventListener('pointerup', this.onPointerup, false); document.removeEventListener('pointermove', this.onPointerMove, false); } addActor(actor) { if (actor instanceof Actor) { this.actors.push(actor); } } runFor(ticks) { let interval = 1 / 60; let i = 0; for (i; i < ticks; i++) { this.triggerEvent('application-animate', { now: this.now, then: this.then, interval: interval, application: this }); this.render(); } } animate(delta) { this.now = Date.now(); let interval = this.now - this.then; this.triggerEvent('application-animate', { now: this.now, then: this.then, interval: interval, application: this }); this.render(delta); this.then = this.now; // remove dead actors if (delta - this.removalTest > 5000 || !this.removalTest) { this.removalTest = delta; for (let i = this.actors.length - 1; i >= 0; i--) { if (this.actors[i].dead === true) { this.actors.splice(i, 1); } } } if (this.animating) { requestAnimationFrame(this.animate); } } render(delta) { let dims = this.dimensions; if (this.animatingOut) { this.opacity += .02; if (this.opacity >= 1) this.animatingOut = false; this.context.fillStyle = `rgba(10,10,10,${this.opacity}`; this.context.fillRect(0, 0, dims.width, dims.height); } if (this.clearOnRedraw == Application.CLEAR) { this.context.clearRect(0, 0, dims.width, dims.height); } else if (this.clearOnRedraw == Application.FADE) { this.context.fillStyle = this.fadeColour; this.context.fillRect(0, 0, dims.width, dims.height); } this.actors.forEach(actor => { actor.render(this); }); } onResize(e) { this.dimensions = new Vector(window.innerWidth * 2, window.innerHeight * 2); } onPointerDown(e) { } onPointerup(e) { } onPointerMove(e) { let pointer = new Vector(e.clientX, e.clientY); this.triggerEvent('application-pointermove', { pointer: pointer }); } triggerEvent(event, data) { if (window.CustomEvent) { var event = new CustomEvent(event, { detail: data }); } else { var event = document.createEvent('CustomEvent'); event.initCustomEvent(event, true, true, data); } document.dispatchEvent(event); } get actors() { if (!this._actors) this._actors = []; return this._actors; } set scaleFactor(value) { if (value >= 1) { this._scaleFactor = value; this.onResize(); } } get scaleFactor() { return this._scaleFactor || 1; } set dimensions(value) { if (value instanceof Vector) { value.scale(this.scaleFactor); this.stage.width = value.width; this.stage.height = value.height; this.context.fillStyle = this.fillColour; this.co.........完整代码请登录后点击上方下载按钮下载查看
网友评论0