生长自由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