Snap: Animating a Shape Along a Path

by boulabiar

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.11.2/TweenMax.min.js"></script>
<script src="http://cdn.jsdelivr.net/snap.svg/0.2.0/snap.svg-min.js"></script>
<div id="controls">
    <input type="range" class="timeline" name="timeline0" min="0" max="100" step="0.1" value="0" />
</div>
<svg id="svgdiv" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="214px" height="84px" viewBox="0 0 214 84" enable-background="new 0 0 214 84" xml:space="preserve"></svg>

CSS

#controls {
    float: right;
    margin: 40px;
}
button {
    width: 100px;
    height: 30px;
}
#svgdiv {
    /* background: url('http://thisisa.simple-url.com/eqTemplate.png'); */
}

JavaScript

$(function () {
    var note = {
        staffPath: 'M21.673,84c-0.001,0,2.009-35.847,30.904-38.285c28-2.208,32.912,29.48,32.912,29.48',
        // notePath: 'M3.926,9.681v0.013C3.972,9.696,4.293,9.74,4.412,9.752c1.601,0.285,3.364,1.23,3.426,3.199l1.771,0.259c0.474-3.216,0.762-5.881,0.133-8.885C9.25,1.657,7.204-0.146,4.601,0.01C1.903,0.17-0.153,2.484,0.009,5.181C0.143,7.445,1.801,9.252,3.926,9.681z',
        notePath: 'M0,10L5,0L10,10z',
        color: '#000000'
    },
    paper = new Snap('#svgdiv'),
    animatePath = function(params, index) {
        var guidePath = paper.select(params.guidePath);
        var shape = paper.path(guidePath.getSubpath(0, 1)).attr({
            stroke: 'none',
            fill: 'none',
            'stroke-width': 2,
            'stroke-linecap': 'round'
        }),
        pathLength = guidePath.getTotalLength();
        var drawLine = function(shape) {
            var offset = pathLength*(shape.length/pathLength),
            notePoint = guidePath.getPointAtLength(shape.length),
            subPath = guidePath.getSubpath(0, offset);
            shape.attr({
                stroke: params.color,
                path: subPath
            });
            var noteHead = paper.select('#noteHead'+index);
            console.log('notePoint.alpha', notePoint.alpha);
            console.log('finalPoint', guidePath.getPointAtLength(pathLength));
            var rotation = (notePoint.alpha !== 90)? 90 : 270;
            noteHead.attr({fill: params.color}).transform('t'+parseInt(notePoint.x-5, 10)+','+parseInt(notePoint.y-5, 10)+'r'+(notePoint.alpha-rotation));
        };
        var tween = TweenMax.to(shape, pathLength/90, {
            length: pathLength,
            onUpdate: drawLine,
            ease: Quad.easeIn,
            onUpdateParams: [shape]
        });
        shape.length = 0;
        return tween;
    },
    createTimeline = function(note) {
        var path = paper.path(note.staffPath),
        noteHead =...