canvas#canvas
.infos
p
|Experiment by
a(href="http://www.arnaudrocca.fr", target="_blank") Arnaud Rocca
View Compiled
html, body
width 100%
height 100%
margin 0
padding 0
overflow hidden
background #8DF
background-image radial-gradient(ellipse farthest-corner at center top, #FFF 0%, #8DF 100%)
background-repeat no-repeat
background-attachment fixed
font-size 10px
canvas
position absolute
display block
.infos
position absolute
margin 0
bottom 10px
right 10px
color #000
font-family sans-serif
font-weight 400
font-size 1rem
line-height .5rem
a
text-decoration none
color #07C
transition .3s
&:hover
color #2AF
View Compiled
window.onload = function() {
'use strict';
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
min = 1.25,
timer = 0,
deltaTime = 0,
lastTime = Date.now();
ctx.translate(width / 2, 100);
window.onresize = function() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
ctx.translate(width / 2, 100);
};
update();
/**
* update
*/
function update() {
deltaTime = Date.now() - lastTime;
lastTime = Date.now();
timer += options.speed * deltaTime / 1000;
ctx.clearRect(-width / 2, -100, width, height);
for (var x = 0; x < options.mapSize; x++) {
for (var y = 0; y < options.mapSize; y++) {
switch(options.direction) {
case 'x':
var z = min + Math.sin(timer + Math.sin((y - x) * options.strength / 10));
break;
case 'y':
var z = min + Math.cos(timer + Math.cos((x + y) * options.strength / 10));
break;
default:
break;
}
drawBlock(x, y, z);
}
}
requestAnimationFrame(update);
}
/**
* drawBlock
* - Draw an isometric block
*
* @param {number} x - The position on X
* @param {number} y - The position on Y
* @param {number} z - The height of the block
*/
function drawBlock(x, y, z) {
var top = '#2AF',
right = '#19E',
left = '#07C';
ctx.save();
ctx.translate((x - y) * options.width / 2, (x + y) * options.height / 2);
// Top
ctx.beginPath();
ctx.moveTo(0, -z * options.height);
ctx.lineTo(options.width / 2, options.height / 2 - z * options.height);
ctx.lineTo(0, options.height - z * options.height);
ctx.lineTo(-options.width / 2, options.height / 2 - z * options.height);
ctx.closePath();
ctx.fillStyle = top;
ctx.fill();
ctx.strokeStyle = left;
ctx.stroke();
// Left
ctx.beginPath();
ctx.moveTo(-options.width / 2, options.height / 2 - z * options.height);
ctx.lineTo(0, options.height - z * options.height);
ctx.lineTo(0, options.height);
ctx.lineTo(-options.width / 2, options.height / 2);
ctx.closePath();
ctx.fillStyle = left;
ctx.fill();
ctx.strokeStyle = left;
ctx.stroke();
// Right
ctx.beginPath();
ctx.moveTo(options.width / 2, options.height / 2 - z * options.height);
ctx.lineTo(0, options.height - z * options.height);
ctx.lineTo(0, options.height);
ctx.lineTo(options.width / 2, options.height / 2);
ctx.closePath();
ctx.fillStyle = right;
ctx.fill();
ctx.strokeStyle = right;
ctx.stroke();
ctx.restore();
}
}
// Options
var Options = function() {
this.mapSize = 12;
this.width = 50;
this.height = 25;
this.speed = 5;
this.strength = 2;
this.direction = 'x';
};
var options = new Options(),
gui = new dat.GUI();
gui.close();
gui.add(options, 'mapSize', 5, 20).step(1);
gui.add(options, 'width', 30, 60);
gui.add(options, 'height', 15, 30);
gui.add(options, 'speed', 1, 10);
gui.add(options, 'strength', 1, 5);
gui.add(options, 'direction', ['x', 'y']);
This Pen doesn't use any external CSS resources.