JavaScript
语言:
JaveScriptBabelCoffeeScript
确定
var settings = {
waveLength: 50,
speed: 40,
randomness: 1.2,
amplitude: 8,
imageUrl: "/uploads/161201/asteroid.png",
pixelSize: 2,
};
function dist(x1, y1, x2, y2) {
var dx = x1 - x2;
var dy = y1 - y2;
return Math.sqrt(dx*dx+dy*dy);
}
class Particle {
constructor (destX, destY, r, g, b) {
this.destX = destX;
this.destY = destY;
this.x = destX;
this.y = destY;
this.r = r;
this.g = g;
this.b = b;
this.random = Math.random();
}
move (tick, centerX, centerY) {
var d = dist(centerX, centerY, this.x, this.y)/settings.waveLength;
this.x = this.destX + Math.cos(d+tick*settings.speed/100) * settings.amplitude + this.random * settings.randomness;
this.y = this.destY + Math.sin(d+tick*settings.speed/100) * settings.amplitude + this.random * settings.randomness;
}
}
class ImageWave {
constructor (canvasId) {
this.canvas = document.getElementById(canvasId);
this.ctx = canvas.getContext("2d");
this.tick = 0;
}
init () {
// A list of all the particles that forms the image
this.particles = [];
// Read more about avoiding tainted canvas:
// https://blog.codepen.io/2013/10/08/cross-domain-images-tainted-canvas/
var img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => {
this.w = this.canvas.width = img.width;
this.h = this.canvas.height = img.height;
this.ctx.drawImage(img, 0, 0);
var tempImage = this.ctx.getImageData(0, 0, img.width, img.height);
var data = tempImage.data;
for(var x = 0; x < img.width; x+=settings.pixelSize) {
for(var y = 0; y < img.height; y+=settings.pixelSize) {
// The buffer is linear, y*w+x is a trick
// to calculate the linear index.
var i = (y * img.width + x)*4;
//var color = `rgb(${data[i]}, ${data[i+1]}, ${data[i+2]})`;
this.particles.push(new Particle(x, y, data[i], data[i+1], data[i+2]));
}
}
}
img.src = settings.imageUrl;
}
draw() {
this.ctx.clearRect(0, 0, this.w, this.h);
this.tick++;
this.particles.forEach(p => {
var x = p.x;
var y = p.y;
if(x >= 0 && x < this.w && y >= 0 && y < this.h) {
//this.ctx.fillStyle = p.color;
var color = `rgb(${p.r}, ${p.g}, ${p.b})`;
this.ctx.fillStyle = color;
this.ctx.fillRect(x, y, settings.pixelSize, settings.pixelSize);
}
p.move(this.tick, this.w/2, this.h/2);
});
requestAnimationFrame(() => this.draw());
}
}
window.onload = function () {
var imageWave = new ImageWave("canvas");
imageWave.init();
imageWave.draw();
var panel = QuickSettings.create(10, 10, "Settings")
.setDraggable(true)
.setCollapsible(true)
.addRange("Wave length", 1, 100, settings.waveLength, 1, val => settings.waveLength = val)
.addRange("Speed", 1, 100, settings.speed, 1, val => settings.speed = val)
.addRange("Randomness", 0.1, 10, settings.randomness, 0.1, val => settings.randomness = val)
.addRange("Amplitude", 1, 20, settings.amplitude, 1, val => settings.amplitude = val)
.addRange("Pixel Size", 1, 10, settings.pixelSize, 1, val => {
settings.pixelSize = val;
imageWave.init();
});
}