Skip to content

Instantly share code, notes, and snippets.

@icio
Created February 15, 2011 01:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save icio/826934 to your computer and use it in GitHub Desktop.
Save icio/826934 to your computer and use it in GitHub Desktop.
Raphael.el.wave
/*
- Example usage of Raphael.el.wave
- Produces: http://i.imgur.com/qAcDJ.png
*/
var paper;
/**
* ENTRY POINT.
*/
window.onload = function()
{
// Construct the SVG paper on the page
paper = Raphael(0, 0, "100%", "100%");
document.body.appendChild(paper.canvas);
// Dashed figure-8 with wave atop
paper.path('M100,100c0,200 400-200 400,0c0,200 -400-200 -400,0z')
.attr('stroke', '#999')
.attr('stroke-dasharray', '-')
.wave(60, 5);
// Wave upon a wave
paper.path('M100,300l400,0')
.attr('stroke', '#999')
.attr('stroke-dasharray', '.')
.wave(5, 100)
.attr('stroke-dasharray', '-')
.wave(50, 10);
};
/**
* Create a path that waves across the base path (this).
*
* @param RaphaelPath path The base path on which to produce the wave
* @param int numSegments The number of waves to draw
* @param float d The distance the control points are from the base path
*
* @return path
*
* @author Paul Scott <paul.scotto@gmail.com>
* @usage http://i.imgur.com/qAcDJ.png
*/
Raphael.el.wave = function(numWaves, d)
{
// Raphael's chosen method of keeping element methods type-specific
if(this.type!="path") return;
// The length of the base path
var pathLength = this.getTotalLength();
// The length of each wave along the base path
var segLength = pathLength / numWaves;
// The components of the svg path
var segments = [];
// Pointers to the points that we use
var a, b, c;
var addPoints = function(a, b) {
// Add a quadratic bezier to the wave path (via a, reaching b)
segments.push('Q'+a.x+','+a.y+' '+b.x+','+b.y);
};
var shiftPoint = function(p, d) {
// Shift point p perpendicularly away from the base path to a distance d
p.alpha *= Math.PI / 180;
p.x -= d * Math.sin(p.alpha);
p.y += d * Math.cos(p.alpha);
return p;
};
// Starting Point
a = this.getPointAtLength(0);
segments.push('M'+a.x+' '+a.y);
// Following Points
c = shiftPoint(this.getPointAtLength(segLength * 0.5), d);
for (var i = 1; i < numWaves; i++)
{
// Reverse the direction of each subsequent wave
d *= -1;
a = c;
c = shiftPoint(this.getPointAtLength(segLength * (i + 0.5)), d);
b = {x: (a.x + c.x) / 2, y: (a.y + c.y) / 2};
addPoints(a, b);
}
// Finalising wave
addPoints(c, this.getPointAtLength(pathLength));
// Create the wave
return this.paper.path(segments.join());
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment