sketch.js
function makePieces(records) {
var pieces = [];
for (var i = 0; i < records.length; i++) {
var r = records[i];
var x1 = r[0] * 1;
var y1 = r[1] * 1;
var x2 = r[2] * 1;
var y2 = r[3] * 1;
var j = r[4];
var t = r[5];
var num = r[6];
pieces.push(new Piece(pieces, x1, y1, x2, y2, j, t, num));
}
return pieces;
}
var Piece = function(parent, x1, y1, x2, y2, jerk, duration, num) {
if (Array.isArray(parent)) {
parent = parent[parent.length - 1];
}
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.jerk = jerk;
this.duration = duration;
this.num = num;
this.length = dist(x1, y1, x2, y2);
if (parent) {
this.t0 = parent.t1;
this.t1 = this.t0 + duration;
this.a0 = parent.a(this.t0);
this.v0 = parent.v(this.t0);
this.x0 = parent.xf;
} else {
this.t0 = 0;
this.t1 = duration;
this.a0 = 0;
this.v0 = 0;
this.x0 = 0;
}
this.xf = this.x0 + this.length;
}
Piece.prototype.hasT = function(t) {
return t >= this.t0 && t < this.t1;
}
Piece.prototype.j = function(t) {
return this.jerk;
}
Piece.prototype.a = function(t) {
t = min(t - this.t0, this.duration);
return this.a0 + this.jerk * t;
}
Piece.prototype.v = function(t) {
t = min(t - this.t0, this.duration);
return this.v0 + this.a0 * t + this.jerk * t * t / 2;
}
Piece.prototype.x = function(t) {
t = min(t - this.t0, this.duration);
var x = this.x0 + this.v0 * t + this.a0 * t * t / 2 + this.jerk * t * t * t / 6;
return min(x, this.xf);
}
function evaluate(pieces, n, t) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].hasT(t) || i == pieces.length - 1) {
switch (n) {
case 0: return pieces[i].x(t);
case 1: return pieces[i].v(t);
case 2: return pieces[i].a(t);
case 3: return pieces[i].j(t);
default: return 0;
}
}
}
return 0;
}
function drawPiece(dc, piece) {
dc.vertex(piece.x1, piece.y1);
dc.vertex(piece.x2, piece.y2);
}
function drawPieceLength(dc, piece, length) {
var x1 = piece.x1;
var y1 = piece.y1;
var x2 = lerp(piece.x1, piece.x2, length / piece.length);
var y2 = lerp(piece.y1, piece.y2, length / piece.length);
dc.vertex(x1, y1);
dc.vertex(x2, y2);
}
function drawPieces(dc, pieces, length) {
if (pieces[0].num % 2 == 0) {
dc.stroke(0);
} else {
dc.stroke(0, 32);
}
dc.beginShape();
for (var i = 0; i < pieces.length; i++) {
if (length <= 0) {
break;
}
var piece = pieces[i];
if (piece.length < length) {
drawPiece(dc, piece);
} else {
drawPieceLength(dc, piece, length);
}
length -= piece.length;
}
dc.endShape();
}
function Drawing(pieces) {
this.pieces = pieces;
this.x = 0;
this.y = 0;
this.w = 300;
this.h = 300;
}
Drawing.prototype.setTransform = function(dc) {
var sx = dc.width / (this.w + 40);
var sy = dc.height / (this.h + 40);
var s = min(sx, sy);
var dx = (dc.width - this.w * s) / 2;
var dy = (dc.height - this.h * s) / 2;
dc.resetMatrix();
dc.translate(dx, dy);
dc.scale(s);
dc.translate(-this.x, -this.y);
}
Drawing.prototype.draw = function(dc, t) {
var length = evaluate(this.pieces, 0, t);
drawPieces(dc, this.pieces, length);
}
Drawing.prototype.done = function(t) {
var pieces = this.pieces;
return t > pieces[pieces.length - 1].t1;
}
var buffer;
var drawing;
var index;
var start;
function setup() {
index = 0;
start = millis() / 1000;
drawing = new Drawing(makePieces(PIECES[index]));
createCanvas(windowWidth, windowHeight);
restart();
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
restart();
}
function setStyle(dc) {
dc.stroke(0);
dc.strokeWeight(1);
dc.strokeJoin(ROUND);
dc.noFill();
}
function restart() {
background(255);
buffer = createGraphics(width, height);
buffer.background(255);
for (var i = 0; i < index; i++) {
var d = new Drawing(makePieces(PIECES[i]));
d.setTransform(buffer);
d.draw(buffer, 1000000);
}
}
function draw() {
resetMatrix();
var t = millis() / 1000 - start;
if (drawing.done(t)) {
setStyle(buffer);
drawing.setTransform(buffer);
drawing.draw(buffer, t);
index++;
start = millis() / 1000;
drawing = new Drawing(makePieces(PIECES[index]));
t = 0;
}
image(buffer, 0, 0);
setStyle(window);
drawing.setTransform(window);
drawing.draw(window, t);
}