Skip to content

Instantly share code, notes, and snippets.

@benpickles
Last active November 9, 2016 14:52
Show Gist options
  • Save benpickles/3d46a3d97410812a3925 to your computer and use it in GitHub Desktop.
Save benpickles/3d46a3d97410812a3925 to your computer and use it in GitHub Desktop.
Freight Train

A train runs along this (randomly generated) track.

var height = 500
, width = 960
var trackGenerator = function(width, height, points) {
var coords = []
for (var i = 0; i < points; i++) {
var x = Math.random() * width
, y = Math.random() * height
coords.push([x, y])
}
return coords
}
var trackCoords = trackGenerator(width, height, 5)
var svg = d3.select('body')
.append('svg')
.attr('height', height)
.attr('width', width)
var line = d3.svg.line()
.interpolate('cardinal-closed')
.tension(0.3)
var track = svg.append('path')
.attr('d', function(d) { return line(trackCoords) })
.style({
fill: 'none',
stroke: '#ccc',
'stroke-width': 6,
})
var carriage = function(width, height, style) {
var group = svg.append('g')
group.append('rect')
.attr('height', height)
.attr('width', width)
.attr('x', -width / 2)
.attr('y', -height / 2)
.style(style)
return group
}
var engine = carriage(30, 10, { fill: 'black' })
, tender = carriage(15, 10, { fill: 'black' })
, carriage1 = carriage(25, 10, { fill: 'purple' })
, carriage2 = carriage(25, 10, { fill: 'blue' })
, carriage3 = carriage(25, 10, { fill: 'green' })
, carriage4 = carriage(25, 10, { fill: 'yellow' })
, carriage5 = carriage(25, 10, { fill: 'orange' })
, carriage6 = carriage(25, 10, { fill: 'red' })
var nodePointMover = function(node) {
var length = node.getTotalLength()
return function(distance) {
distance = distance % length
if (distance < 0) distance += length
var p0 = node.getPointAtLength(distance)
, p1 = node.getPointAtLength(distance + 1)
, dx = p1.x - p0.x
, dy = p1.y - p0.y
, angle = Math.atan2(dy, dx) * 180 / Math.PI
, translate = 'translate(' + p0.x + ',' + p0.y + ')'
, rotate = 'rotate(' + angle + ')'
return translate + rotate
}
}
var moveToPointAtLength = nodePointMover(track.node())
var postionTrain = function(distance) {
engine.attr('transform', moveToPointAtLength(distance))
tender.attr('transform', moveToPointAtLength(distance - 25))
carriage1.attr('transform', moveToPointAtLength(distance - 48))
carriage2.attr('transform', moveToPointAtLength(distance - 76))
carriage3.attr('transform', moveToPointAtLength(distance - 104))
carriage4.attr('transform', moveToPointAtLength(distance - 132))
carriage5.attr('transform', moveToPointAtLength(distance - 160))
carriage6.attr('transform', moveToPointAtLength(distance - 188))
}
var lastStamp = 0
, distance = 0
, speed = 100
var draw = function(timestamp) {
if (!lastStamp) lastStamp = timestamp
var diff = timestamp - lastStamp
lastStamp = timestamp
distance += speed * (diff / 1000)
postionTrain(distance)
requestAnimationFrame(draw)
}
requestAnimationFrame(draw)
<!DOCTYPE html>
<html>
<head>
<title>Freight Train</title>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="app.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment