Built with blockbuilder.org
Last active
September 2, 2019 08:15
-
-
Save GitNoise/9315f081db45ddb9cd017d282ba11307 to your computer and use it in GitHub Desktop.
Split circles animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
.dot { | |
fill: rgb(255, 0, 0); | |
} | |
.center { | |
fill: rgb(0, 0, 255, 0.5); | |
stroke: rgba(0, 0, 255, 1); | |
r: 10; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
const width = 500, | |
height = 500; | |
const centerCoord = [width/2, height/2] | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
const drawDots = function(data, duration) { | |
return new Promise(function(resolve, reject) { | |
var dots = svg.selectAll('.dot') | |
.data(data, d => d.id) | |
const transition = d3.transition() | |
.duration(duration) | |
.end().then(resolve); | |
dots | |
.transition(transition) | |
.duration(duration) | |
.ease(d3.easeBack) | |
.attr('cx', d => d.x) | |
.attr('cy', d => d.y) | |
.attr('r', d => d.r) | |
dots.enter() | |
.append('circle') | |
.classed('dot', true) | |
.attr('r', d => d.r) | |
.attr('cx', d => d.x) | |
.attr('cy', d => d.y) | |
dots.exit() | |
.remove(); | |
}); | |
} | |
const dataSimulation = new Promise(function(resolve, reject) { | |
const noOfDots = 100; | |
const data = d3.range(noOfDots).map((d, i) => ( | |
{ | |
id: `dot${i}`, | |
x: centerCoord[1], | |
y: centerCoord[0], | |
r: 5 | |
} | |
)); | |
const steps = 300; | |
const force = d3.forceSimulation() | |
.nodes(data) | |
.force('collision', d3.forceCollide().radius(7).strength(1/steps * 10)) | |
.alphaDecay(1 - Math.pow(0.001, 1 / (steps / 2))) | |
.on('end', () => resolve(data)) | |
}); | |
async function myMain() { | |
/****************** DATA *************/ | |
const dataInitial = [ | |
{id: 'dot_1', y: height*.2, x: width*.4, r: 20}, | |
{id: 'dot_2', y: height*.3, x: width*.6, r: 30}, | |
{id: 'dot_3', y: height*.4, x: width*.2, r: 30}, | |
]; | |
const dataCentered = dataInitial.map(d => ( | |
{ | |
id: d.id, | |
y: centerCoord[0], | |
x: centerCoord[1], | |
r: 5, | |
} | |
)); | |
const dataSimulated = await dataSimulation; | |
const dataSimualtedCentered = dataSimulated.map(d => ({ | |
id: d.id, | |
y: centerCoord[0], | |
x: centerCoord[1], | |
r: 5, | |
})); | |
const splitKeep = dataSimulated.slice(0, Math.round(dataSimulated.length * 0.25)); | |
let splitRemove = dataSimulated.slice(splitKeep.length) | |
splitRemove = splitRemove.map(d => ({ | |
id: d.id, | |
x: width * 2, | |
y: d.y, | |
r: d.r, | |
})); | |
const dataSimulatedSplit = splitKeep.concat(splitRemove); | |
// create animation steps | |
const animationSteps = [ | |
dataInitial, | |
dataCentered, | |
dataSimulated, | |
dataSimulatedSplit, | |
dataSimualtedCentered, | |
]; | |
/******* Draw dots ***********/ | |
// draw large dots | |
await drawDots(animationSteps[0], 1000); | |
while(true) { | |
// center large dots | |
await drawDots(animationSteps[1], 2000); | |
await drawDots(animationSteps[4], 0); | |
// create small dots and remove large dots | |
await drawDots(animationSteps[2], 2000); | |
// split small dots | |
await drawDots(animationSteps[3], 2000); | |
// merge small dots | |
await drawDots(animationSteps[2], 2000); | |
// center small dots | |
await drawDots(animationSteps[4], 2000); | |
// remove small dots and create large dots | |
await drawDots(animationSteps[1], 0); | |
// move large dots to intial position | |
await drawDots(animationSteps[0], 1000); | |
} | |
} | |
myMain(); | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment