Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<br>
<button id="animate">Generate New Points</button>
<br>
<br>
<body>
<script>
//three random data points.
var data = [{xval:Math.random(),yval:Math.random()},
{xval:Math.random(),yval:Math.random()},
{xval:Math.random(),yval:Math.random()}]
var height = 300;
var width = 500;
var radius = 5;
//define x-y scale like normal.
var xScale = d3.scaleLinear()
.domain([0,1])
.range([0,width])
var yScale = d3.scaleLinear()
.domain([0,1])
.range([height,0])
var canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height)
.style("border","1px solid black")
//get context where circles will be drawn.
var context = canvas.node().getContext("2d");
data.forEach(function(d){
//loop through data and draw a circle for each data point.
context.strokeStyle = "red"
context.beginPath();
context.arc(xScale(d.xval), yScale(d.yval), radius, 0, 2 * Math.PI, true);
context.fillStyle = "black"
context.fill();
context.stroke();
})
d3.select("#animate").on("click",animate)
function animate(){
//set new data, record source location, and manually interpolate to the new value.
data.forEach(function(d){
//attach starting location to data (what we will interpolate FROM)
d.sx = xScale(d.xval)
d.sy = yScale(d.yval)
//generate a new data point.
d.xval = Math.random();
d.yval = Math.random();
//attach the ending location (what we will interpolate TO)
d.tx = xScale(d.xval)
d.ty = yScale(d.yval)
})
var duration = 1000;
var ease = d3.easeCubic;
//initialize a timer function to use for animation.
d3.timer(function (elapsed) {
//calculate how far through the animation we are.
let t = Math.min(elapsed/duration, 1);
//clear cavas on each loop.
context.clearRect(0, 0, width, height);
//update the canvas based on the interpolated values.
data.forEach(function(d){
//loop through data and draw a circle for each data point.
context.strokeStyle = "red"
context.beginPath();
context.arc(d3.interpolate(d.sx,d.tx)(t), d3.interpolate(d.sy,d.ty)(t), radius, 0, 2 * Math.PI, true);
context.fillStyle = "black"
context.fill();
context.stroke();
})
if (t === 1) {
//stop timer.
return true;
}
});
}
</script>
</body>
https://d3js.org/d3.v4.min.js