Overlapping rotated squares create a scaly look. Add some math and majesty, and they come to life.
a.style.cssText="width:auto;height:auto;margin:auto;position:absolute;top:0;right:0;bottom:0;left:0";b.style.background="#000";e=Date.now();f=0;g=Math;d();h();function d(){j=a.width=0.5*innerWidth;k=a.height=0.5*innerHeight;l=(j+k)/8;m=g.ceil(j/l)+1;n=4*g.ceil(k/l)+2;o=15;p=l/4;q=g.PI/40;r=g.max(2,l/50);s=g.max(6,l/12)}function h(){requestAnimationFrame(h);for(t=n;t--;)for(u=p/2+g.sin((f+t)/o)*p,y=((t-2)*l+l/2)/4,v=100-(4*t+-f/2),w=m;w--;)x=t%2?w*l+l/2:w*l,c.save(),c.translate(x-u,y),c.rotate(g.PI/4+g.cos((f+t)/o)*q),c.beginPath(),c.rect(-l/2,-l/2,l,l),c.lineWidth=r,c.strokeStyle=0.98<g.random()?"hsl("+v+",100%,"+(60+20*g.random())+"%)":"hsl("+v+",100%,60%)",c.stroke(),c.lineWidth=s,c.strokeStyle="rgba(0,0,0,.25)",c.stroke(),c.fillStyle="hsl("+v+",80%,20%)",c.fill(),c.restore();y=Date.now();f+=(y-e)/16.6;e=y}
onresize=d
YS5zdHlsZS5jc3NUZXh0PSJ3aWR0aDphdXRvO2hlaWdodDphdXRvO21hcmdpbjphdXRvO3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO3JpZ2h0OjA7Ym90dG9tOjA7bGVmdDowIjtiLnN0eWxlLmJhY2tncm91bmQ9IiMwMDAiO2U9RGF0ZS5ub3coKTtmPTA7Zz1NYXRoO2QoKTtoKCk7ZnVuY3Rpb24gZCgpe2o9YS53aWR0aD0wLjUqaW5uZXJXaWR0aDtrPWEuaGVpZ2h0PTAuNSppbm5lckhlaWdodDtsPShqK2spLzg7bT1nLmNlaWwoai9sKSsxO249NCpnLmNlaWwoay9sKSsyO289MTU7cD1sLzQ7cT1nLlBJLzQwO3I9Zy5tYXgoMixsLzUwKTtzPWcubWF4KDYsbC8xMil9ZnVuY3Rpb24gaCgpe3JlcXVlc3RBbmltYXRpb25GcmFtZShoKTtmb3IodD1uO3QtLTspZm9yKHU9cC8yK2cuc2luKChmK3QpL28pKnAseT0oKHQtMikqbCtsLzIpLzQsdj0xMDAtKDQqdCstZi8yKSx3PW07dy0tOyl4PXQlMj93KmwrbC8yOncqbCxjLnNhdmUoKSxjLnRyYW5zbGF0ZSh4LXUseSksYy5yb3RhdGUoZy5QSS80K2cuY29zKChmK3QpL28pKnEpLGMuYmVnaW5QYXRoKCksYy5yZWN0KC1sLzIsLWwvMixsLGwpLGMubGluZVdpZHRoPXIsYy5zdHJva2VTdHlsZT0wLjk4PGcucmFuZG9tKCk/ImhzbCgiK3YrIiwxMDAlLCIrKDYwKzIwKmcucmFuZG9tKCkpKyIlKSI6ImhzbCgiK3YrIiwxMDAlLDYwJSkiLGMuc3Ryb2tlKCksYy5saW5lV2lkdGg9cyxjLnN0cm9rZVN0eWxlPSJyZ2JhKDAsMCwwLC4yNSkiLGMuc3Ryb2tlKCksYy5maWxsU3R5bGU9ImhzbCgiK3YrIiw4MCUsMjAlKSIsYy5maWxsKCksYy5yZXN0b3JlKCk7eT1EYXRlLm5vdygpO2YrPSh5LWUpLzE2LjY7ZT15fQ0Kb25yZXNpemU9ZA==
a.style.cssText = 'width:auto;height:auto;margin:auto;position:absolute;top:0;right:0;bottom:0;left:0'; // reset css dimensions and center
b.style.background = '#000'; // dark background
lt = Date.now() // last time
et = 0 // elapsed time
M = Math
reset()
loop()
function reset() {
// new dimensions
w = a.width = innerWidth * .5
h = a.height = innerHeight * .5
dim = ( w + h ) / 8 // base dimension
cols = M.ceil( w / dim ) + 1 // columns
rows = M.ceil( h / dim ) * 4 + 2 // rows
div = 15 // timing division for translation and rotation
shift = dim / 4 // horizontal shifting
rot = M.PI / 40 // rotation range
lw1 = M.max( 2, dim / 50 ) // outline width
lw2 = M.max( 6, dim / 12 ) // shadow width
}
function loop() {
requestAnimationFrame( loop )
for( i = rows; i-- ; ) { // loop through rows
xoff = ( shift / 2 ) + M.sin( ( et + i ) / div ) * shift // x offset for this row
y = ( ( i - 2 ) * dim + dim / 2 ) / 4 // y value for row
hue = 100 - ( i * 4 + -et / 2 ) // hue for row
for( j = cols; j--; ) { // loop through columns
x = i % 2 ? j * dim + dim / 2 : j * dim // x value for column - staggered
c.save()
// move and spin
c.translate( x - xoff, y )
c.rotate( ( M.PI / 4 ) + M.cos( ( et + i ) / div ) * rot )
c.beginPath()
// main shape
c.rect( -dim / 2, -dim / 2, dim, dim )
// outline
c.lineWidth = lw1
c.strokeStyle = M.random() > .95 ? 'hsl(' + hue + ',100%,' + ( 60 + M.random() * 20 ) + '%)' : 'hsl(' + hue + ',100%,60%)'
c.stroke()
// shadow
c.lineWidth = lw2
c.strokeStyle = 'rgba(0,0,0,.25)'
c.stroke()
// main fill
c.fillStyle = 'hsl(' + hue + ',80%,20%)'
c.fill()
c.restore()
}
}
// elapsed time
now = Date.now()
et += ( now - lt ) / 16.6
lt = now
}
// scale to the window
onresize = reset