Skip to content

Instantly share code, notes, and snippets.

@joyrexus
Created October 13, 2013 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joyrexus/6956598 to your computer and use it in GitHub Desktop.
Save joyrexus/6956598 to your computer and use it in GitHub Desktop.
Animate path of bug along a curve

Animate the movement of a bug along a curve while tracing/erasing path.

Demonstrates how to use the getTotalLength and getPointAtLength methods on SVG path elements to interpolate a point along an existing path ... as well as how to animate the path using "stroke-dash interpolation", previously demo-ed here.

Built with svg.js and inspired by @johan's much slicker D3-variant. Also check out @mbostock's Stroke Dash Interpolation block.

<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://jashkenas.github.io/coffee-script/extras/coffee-script.js"></script>
<script src="https://s3-eu-west-1.amazonaws.com/svgjs/svg.js"></script>
<style>
path {
fill: none;
stroke: #999;
stroke-width: 1.5px;
}
circle, ellipse {
fill: steelblue;
stroke: white;
stroke-width: 1.5px;
}
</style>
<body>
<div id="canvas"></div>
<script type="text/coffeescript">
w = 960
h = 500
draw = SVG('canvas').size(w, h)
curveSpec = """
M192,355
L224, 365.626
C256, 376.35, 320, 397.8, 384, 359.67
C448, 321.54, 512, 223.837, 570, 192.8
C628, 161.755, 680, 197.78, 706, 215.19
L732, 233
"""
draw.path(curveSpec, true).attr("id", "curve")
curve = document.querySelector "#curve"
length = curve.getTotalLength()
origin = curve.getPointAtLength 0
curve.style.transition = 'none' # clear any previous transition
curve.style.strokeDasharray = "#{length} #{length}"
curve.style.strokeDashoffset = length
curve.getBoundingClientRect() # trigger layout to set styles
bug = draw.circle(13).center(origin.x, origin.y)
bug.moveAlong = (path, reverse=false, duration=2000) ->
timer = draw.circle(0).animate(duration)
# t ranges from 0 to 1 over the duration of the timer
transition = (t) =>
t = 1 - t if reverse
curve.style.strokeDashoffset = length - t * length
point = path.getPointAtLength t * length
@center point.x, point.y
timer.during(transition)
reverse = true
run = ->
reverse = not reverse # reverse direction on next run
bug.moveAlong(curve, reverse).after(run)
run()
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment