kleinesbuero/htdocs/kleinesbuero.js

208 lines
No EOL
5.2 KiB
JavaScript

class Wiggler {
constructor(canvas, target) {
console.log("start init")
this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this.target = target;
this.width = this.canvas.width;
this.height = this.canvas.height;
// this.initRandom();
// this.initCorners();
this.current = this.initEdges();
}
initRandom() {
return this.target.map(l => {
const px = Math.random() * this.width;
const py = Math.random() * this.height;
const r = Math.PI * 2;
const tx = px + Math.cos(r) * 10;
const ty = py + Math.sin(r) * 10;
return [[px, py], [tx, ty]];
});
}
initCorners() {
return this.target.map(l => {
const px = Math.random() < .5 ? 0 : this.width;
const py = Math.random() < .5 ? 0 : this.height;
const r = Math.PI * 2;
const tx = px + Math.cos(r) * 10;
const ty = py + Math.sin(r) * 10;
return [[px, py], [tx, ty]];
});
}
initEdges() {
return this.target.map(() => {
var px, py;
if (Math.random() < .5) {
px = Math.random() < .5 ? 0 : this.width;
py = Math.random() * this.height;
} else {
px = Math.random() * this.width;
py = Math.random() < .5 ? 0 : this.height;
}
return [[px, py], [px, py]];
});
}
start() {
console.log("start");
if (!this.running) {
this.running = true;
this.animate();
}
}
stop() {
console.log("stop");
if (this.running) {
this.running = false;
}
}
toggle() {
this.running = !this.running;
if (this.running) {
this.animate();
} else {
console.log("stop");
}
}
animate() {
if (this.running) {
this.update();
this.draw();
window.requestAnimationFrame(() => { this.animate(); })
}
}
dist(p1, p2) {
const dx = p1[0] - p2[0];
const dy = p1[1] - p2[1];
return Math.sqrt(dx * dx + dy * dy);
}
mv(d) { return Math.random() * d - (d / 2.0); }
update() {
var changed = false;
for (var l = 0; l < this.current.length; l++) {
for (var p = 0; p < 2; p++) {
const cp = this.current[l][p];
const tp = this.target[l][p];
if (this.dist(cp, tp) > .5) {
changed = true;
const dist = this.dist(cp, tp);
var np;
var ndist;
do {
const dx = this.mv(Math.sqrt(dist) + 2);
const dy = this.mv(Math.sqrt(dist) + 2);
np = [cp[0] + dx, cp[1] + dy];
ndist = this.dist(np, tp);
} while (ndist > dist);
this.current[l][p] = np;
}
}
}
if (!changed) {
this.running = false;
}
}
draw() {
this.fillStyle = "white";
this.ctx.clearRect(0, 0, 800, 600);
this.ctx.strokeStyle = "black";
this.current.forEach(l => {
this.ctx.beginPath();
this.ctx.moveTo(l[0][0], l[0][1]);
this.ctx.lineTo(l[1][0], l[1][1]);
this.ctx.stroke();
});
}
mash() {
// randomize completely
// this.current = this.current.map(l => l.map(p => [p[0] + Math.random() * 300 - 150, p[1] + Math.random() * 300 - 150]));
this.current = this.current.map(l => {
const px = l[0][0] + this.mv(this.width / 5);
const py = l[0][1] + this.mv(this.height / 5);
const r = Math.PI * 2;
const tx = px + Math.cos(r) * 10;
const ty = py + Math.sin(r) * 10;
return [[px, py], [px, py]];
});
if (!this.running) {
this.running = true;
this.animate();
}
}
}
Array.__prototype
const textToCoords = (text, scale, alphabet) => {
var base = 0;
var output = Array.from(text).flatMap(c => {
const g = alphabet[c].map(l =>
l.map(p => [p[0] * scale + base, p[1] * scale])
);
const maxx = alphabet[c].map(l => Math.max(l[0][0], l[1][0]));
// width of character plus
const inc = (Math.max(1, Math.max(...maxx)) + 0.2) * scale;
base += inc;
return g;
});
return output;
/*
for (var i = 0; i < text.length; i++) {
const char = text[i];
const co = alphabet[char];
co.forEach(l => output.push(l.map(p => p.map())));
}
*/
};
document.addEventListener('DOMContentLoaded', () => {
console.log("kleines büro ready ...");
const canvas = document.getElementById("header");
const target = textToCoords("KLEINES BÜRO", 10, alphabet);
const wiggler = new Wiggler(canvas, target);
wiggler.start();
canvas.addEventListener("click", () => { wiggler.mash(); });
new Splide('.splide', {
padding: '5rem',
}).mount();
});