JSFiddle - React, Tailwind, and code Playground
by egon
HTML
<div>
<button id="alpha">alpha</button>
<button id="beta">beta</button>
<button id="gamma">gamma</button>
<button id="delta">delta</button>
</div>
<canvas id="main"></canvas>
CSS
canvas { border: 1px solid #000;}
JavaScript
document.getElementById("alpha").onclick = function(){ openNewPage("alpha") };
document.getElementById("beta").onclick = function(){ openNewPage("beta") };
document.getElementById("gamma").onclick = function(){ openNewPage("gamma") };
document.getElementById("delta").onclick = function(){ openNewPage("delta") };
var Size = {x:640,y:480};
var Padding = 20;
// slow down here if needed
var Speed = 0.7;
function dist(a, b) {
var dx = a.x - b.x,
dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy);
}
function now(){ return (new Date())|0; }
var canvas = document.getElementById("main");
var context = canvas.getContext("2d");
canvas.width = Size.x;
canvas.height = Size.y;
var pages = [];
function newPage(caption) {
return {
caption: caption,
hue: ((Math.random()*360)|0),
get fillStyle() { return "hsla(" + this.hue + ", 50%, 70%, 0.5)"},
get strokeStyle() { return "hsla(" + this.hue + ", 50%, 30%, 0.5)"},
pos: {x: Padding, y: -Size.y},
speed: {x: 0, y: 10},
size: {x: 300, y: Size.y - 2*Padding},
state: "entering",
update: function(dT){
if(this.state == "final"){
return;
}
var target = {x: Padding, y: Padding};
if(this.state == "leaving"){
target = {
x: Padding,
y: 2*Size.y + Padding
};
}
var pos = this.pos;
// (ideally this would be quadratic easing)
var p = 0.9;
var delta = p*target.y + (1-p)*pos.y - pos.y;
pos.y += delta * dT * Speed / 100;
if(dist(pos, target) < 1){
pos.x = target.x;
pos.y = target.y;
this.state = "final";
}
if(pos.y > Size.y) { this.state = "left"; }
},
render: function(context){
context.beginPath();
context.fillStyle = this.fillStyle;
context.strokeStyle = this.strokeStyle;
context.lineWidth = 2;
context.rect(this.pos.x, this.pos.y,
this.size.x, this.size.y);
...