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);
        ...