index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<meta charset='UTF-8'>
<script src="https://d3js.org/d3.v4.min.js"></script>
<title>Coördinator Transition</title>
<style>
html, body {
padding: 0;
margin: 0;
}
body {
background-color: #ffffff;
}
</style>
</head>
<body>
</body>
</html>
<script>
const width = 1400;
const height = 800;
const duration = 5000;
const eases = [ d3.easeCubic ];
let timer;
let currLayout = 1;
let currEase = 0;
function draw( t, points ) {
ctx.save();
ctx.clearRect( 0, 0, width, height );
for (let i = 0; i < points.length; ++i) {
const point = points[i];
const radius = 2;
ctx.beginPath();
ctx.arc( point.x, point.y, radius, 0, 2*Math.PI, false );
ctx.closePath();
ctx.fillStyle = "#cccccc";
ctx.fill()
}
ctx.restore();
}
function animate( oldPoints, newPoints, layouts, eases ) {
const points = [];
const shuffledNewPoints = d3.shuffle( newPoints );
oldPoints.forEach(( point, i ) => {
newPoint = {};
newPoint.sx = point.x;
newPoint.sy = point.y;
newPoint.x = newPoint.tx = shuffledNewPoints[i].x;
newPoint.y = newPoint.ty = shuffledNewPoints[i].y;
points.push( newPoint );
});
ease = eases[ currEase ];
timer = d3.timer(( elapsed ) => {
const t = Math.min(1, ease( elapsed / duration ));
points.forEach(point => {
point.x = point.sx * (1 - t) + point.tx * t;
point.y = point.sy * (1 - t) + point.ty * t;
});
draw( t, points );
if (t === 1) {
timer.stop();
currLayout = (currLayout + 1) % layouts.length;
currEase = ( currEase + 1) % eases.length;
setTimeout(animate, 1500, points, layouts[currLayout], layouts, eases );
}
});
}
const screenScale = window.devicePixelRatio || 1;
const canvas = d3.select('body').append('canvas')
.attr( 'width', width * screenScale)
.attr( 'height', height * screenScale )
.style( 'width', `${width}px` )
.style( 'height', `${height}px` )
canvas.node().getContext( '2d' ).scale( screenScale, screenScale );
const ctx = canvas.node().getContext( '2d' );
ctx.globalAlpha = 0.8;
d3.json( "./coordinates-exotic.json", data => {
const layouts = [];
Object.keys( data ).forEach( key => {
let layout = [];
data[ key ].forEach( point => {
layout.push({
x: point[0],
y: point[1]
});
});
layouts.push( layout );
});
animate( layouts[0], layouts[1], layouts, eases );
});
</script>