Created
November 25, 2010 05:25
-
-
Save brysonian/714947 to your computer and use it in GitHub Desktop.
A little hacky class to allow you to animate along a path from a SVG file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
A simple hacky class that takes a path from an PShape and provides functionality similar to bezierPoint on the path. Makes it easy to create animations along a path. | |
More at https://gist.github.com/714947 | |
*/ | |
class SVGPathAnimation | |
{ | |
ArrayList<SVGBezier> beziers; | |
int length; | |
SVGPathAnimation(PShape path) { | |
beziers = new ArrayList(); | |
int index = 0; | |
PVector[] vecs = new PVector[path.getVertexCodeCount() * 3]; | |
for (int i = 0; i < path.getVertexCodeCount(); i++) { | |
switch (path.getVertexCode(i)) { | |
case PShape.VERTEX: | |
vecs[index] = new PVector(path.getVertexX(index), path.getVertexY(index)); | |
index++; | |
break; | |
case PShape.BEZIER_VERTEX: | |
vecs[index] = new PVector(path.getVertexX(index), path.getVertexY(index)); | |
vecs[index+1] = new PVector(path.getVertexX(index+1), path.getVertexY(index+1)); | |
vecs[index+2] = new PVector(path.getVertexX(index+2), path.getVertexY(index+2)); | |
index += 3; | |
break; | |
} | |
} | |
// ok, add the beziers | |
for(int i=0; i<vecs.length-3; i+=3) { | |
if ((vecs[i] != null) && (vecs[i+1] != null) && (vecs[i+2] != null) && (vecs[i+3] != null)) { | |
SVGBezier b = new SVGBezier(vecs[i], vecs[i+1], vecs[i+2], vecs[i+3]); | |
addBezier(b); | |
} | |
} | |
length = beziers.size(); | |
} | |
void addBezier(SVGBezier b) { | |
beziers.add(b); | |
} | |
PVector pointAt(float t) { | |
int bIndex = floor(length * t); | |
float bTime = (length * t) - bIndex; | |
return beziers.get(bIndex).pointAt(bTime); | |
} | |
} | |
class SVGBezier | |
{ | |
PVector control1, control2, start, end; | |
SVGBezier(PVector s, PVector cp1, PVector cp2, PVector e) { | |
start = new PVector(s.x, s.y); | |
control1 = new PVector(cp1.x, cp1.y); | |
control2 = new PVector(cp2.x, cp2.y); | |
end = new PVector(e.x, e.y); | |
} | |
void draw() { | |
bezier(start.x, start.y, | |
control1.x, control1.y, | |
control2.x, control2.y, | |
end.x, end.y); | |
} | |
PVector pointAt(float t) { | |
float x = bezierPoint(start.x, control1.x, control2.x, end.x, t); | |
float y = bezierPoint(start.y, control1.y, control2.y, end.y, t); | |
return new PVector(x, y); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Example program showing how to use the SVGPathAnimation class. | |
More at https://gist.github.com/714947 | |
*/ | |
PShape path; | |
SVGPathAnimation ani; | |
float step = 0; | |
int steps = 100; | |
void setup() { | |
size(500, 500); | |
smooth(); | |
path = loadShape("path.svg"); | |
ani = new SVGPathAnimation(path.getChild(0)); | |
} | |
void draw() { | |
background(255); | |
shape(path, 0, 0); | |
fill(0); | |
noStroke(); | |
PVector v = ani.pointAt(step / steps); | |
ellipse(v.x, v.y, 10, 10); | |
step++; | |
if (step >= steps) step = 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment