Skip to content

Instantly share code, notes, and snippets.

@mindrones
Last active November 30, 2017 12:11
Show Gist options
  • Save mindrones/123832bbf5b08ce4b28dab66fae21a69 to your computer and use it in GitHub Desktop.
Save mindrones/123832bbf5b08ce4b28dab66fae21a69 to your computer and use it in GitHub Desktop.
Infinite race
license: mit

In this infinite race, players gets higher score if they're slower or if they start with higher delay.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Infinite race</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin:0;
position:fixed;
top:0;
right:0;
bottom:0;
left:0;
background: black;
}
svg text {
text-anchor: middle;
dominant-baseline: middle;
fill: black;
stroke: none;
}
</style>
</head>
<body>
<script>
const width = window.innerWidth;
const height = window.innerHeight;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
const AMOUNT = 10;
const RADIUS = 0.5 * height / AMOUNT;
const RACE = width - RADIUS;
const MAX_DELAY = 5000;
const MAX_DURATION = 5000;
const delay = () => MAX_DELAY * Math.random();
const duration = () => MAX_DURATION * Math.random();
const rows =
svg.selectAll('.row')
.data(d3.range(AMOUNT).map(i => ({score:0})));
const enter =
rows.enter()
.append('g')
.attr('class', 'row')
.attr('transform', (d, i) => `translate(0,${RADIUS * (1+ 2 * i)})`)
.append('g')
.attr('class', 'player')
.attr('transform', `translate(${RADIUS},0)`)
enter
.append('circle')
.attr('r', RADIUS)
.attr('fill', d3.interpolateCool(0));
enter
.append('text')
.attr('font-size', 0.8 * RADIUS)
.text(d => d.score)
let endCount = 0;
let startCount = 0;
let maxScore = 0;
const player = d3.selectAll('.player');
const size = player.size();
player.call(forth);
function updatePlayer (sel) {
sel.select('circle')
.attr('fill', d => d3.interpolateCool(d.score / maxScore));
sel.select('text')
.text(d => d.score);
}
function started (d) {
startCount +=1;
d.score = startCount;
maxScore = d3.max([d.score, maxScore]);
player.call(updatePlayer);
}
function ended (fn) {
return d => {
endCount +=1;
d.score += endCount;
maxScore = d3.max([d.score, maxScore]);
player.call(updatePlayer);
if (endCount === size) {
endCount = 0;
startCount = 0;
player.call(fn);
};
}
}
function forth (sel) {
sel.transition()
.duration(duration)
.delay(delay)
.attr('transform', `translate(${RACE},0)`)
.on('start', started)
.on('end', ended(back));
}
function back (sel) {
sel.transition()
.duration(duration)
.delay(delay)
.attr('transform', `translate(${RADIUS},0)`)
.on('start', started)
.on('end', ended(forth));
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment