Livecoding my father's idea with him, using ES2015 and transitions whose duration is longer than the iteration loop in which the exit transition is a bit tricky with D3 3.*.
Built with blockbuilder.org
Livecoding my father's idea with him, using ES2015 and transitions whose duration is longer than the iteration loop in which the exit transition is a bit tricky with D3 3.*.
Built with blockbuilder.org
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
svg { width:100%; height: 100% } | |
</style> | |
</head> | |
<body> | |
<script> | |
var svg = d3.select("body").append("svg") | |
const width = 960 | |
const height = 500 | |
const starNumber = 300 | |
svg.attr({width, height}) | |
svg.style({ | |
'background-color': 'black' | |
}) | |
const randomStar = () => ({ | |
key: Math.random(), | |
x: width * Math.random(), | |
y: height * Math.random(), | |
existing: true | |
}) | |
const starData = Array.apply(null, Array(starNumber)).map(randomStar) | |
window.setInterval(() => { | |
const stars = svg.selectAll('.star').data(starData, d => d.key) | |
stars.enter().append('circle').classed('star', true) | |
stars.attr({ | |
r: 1, | |
fill: 'white', | |
cx: d => d.x, | |
cy: d => d.y, | |
opacity: 1 | |
}) | |
const timing = Math.random() * 1000 + 250 | |
const maxSize = Math.random() * 100 + 5 | |
stars.exit() | |
.filter(d => d.existing) | |
.each(d => {d.existing = false}) | |
.transition().duration(timing).ease('cubic-in') | |
.attr({ | |
r: maxSize, | |
opacity: 0.5 | |
}) | |
.transition().duration(timing/4).ease('cubic-out') | |
.attr({ | |
r: 0, | |
opacity: 0 | |
}) | |
.remove() | |
starData.shift() | |
starData.push(randomStar()) | |
}, 250) | |
</script> | |
</body> |