Skip to content

Instantly share code, notes, and snippets.

@enjalot
Last active August 29, 2015 14:24
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 enjalot/61d5eda6f36526d9feea to your computer and use it in GitHub Desktop.
Save enjalot/61d5eda6f36526d9feea to your computer and use it in GitHub Desktop.
phat path draw anim
{"description":"phat path draw anim","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"points.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"loop":true,"restart":false,"autoinit":true,"pause":true,"loop_type":"pingpong","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"ajax-caching":true,"thumbnail":"http://i.imgur.com/fBU5zMN.gif","inline-console":false,"controls":{"Amplitude Top":100,"tang":100,"tangent":52,"tangent at":50,"tangent at ":50,"tangent at percent":59}}
var height = 150;
var cm = tributary.getCodeEditor("points.json");
var points = JSON.parse(cm.getValue())
// lets use percentage of the length to determine where we take tangent;
var tangentAt = 38;
// the amount to phatten the path by
var vectorScale = 20;
// the number of samples
var numSamples = 142
var pathWidth = 21;
var sampleWidth = 18;
var circleRadius = 18;
var line = d3.svg.line()
.x(function(d) { return d.x })
.y(function(d) { return d.y })
.interpolate("cardinal")
//.interpolate("basis")
var svg = d3.select("svg")
var path = svg.append("path")
.style({
fill: "none",
stroke: "none",
"stroke-width": pathWidth
})
var drag = d3.behavior.drag()
.on("drag", function(d) {
d.x = d3.mouse(this)[0];
d.y = d3.mouse(this)[1];
samples = getSamples(node, numSamples);
draw()
})
.on("dragend", function() {
save();
})
svg.on("dblclick", function() {
points.push({x: d3.mouse(this)[0], y: d3.mouse(this)[1] });
samples = getSamples(node, numSamples);
draw();
save();
})
path.attr("d", line(points));
var node = path.node()
var samples = getSamples(node, numSamples);
color = d3.scale.category20();
function draw() {
path.attr("d", line(points));
var slines = svg.selectAll("line.perp")
.data(samples);
slines.exit().remove();
slines.enter()
.append("line").classed("perp", true)
slines
.attr({
x1: function(d,i) { return d.point.x - d.perp.x * scale(i) },
y1: function(d,i) { return d.point.y - d.perp.y * scale(i) },
x2: function(d,i) { return d.point.x + d.perp.x * scale(i) },
y2: function(d,i) { return d.point.y + d.perp.y * scale(i) },
//stroke: "#5f55e1",
stroke: function(d,i) {
return color(i);
},
"stroke-width": sampleWidth,
"stroke-opacity": 0.5
})
var circles = svg.selectAll("circle")
.data(points);
circles.exit().remove();
circles
.enter().append("circle")
circles
.attr({
cx: function(d) { return d.x },
cy: function(d) { return d.y },
r: circleRadius,
fill: "#de9090",
"fill-opacity": 0.06,
stroke: "#c9c9c9"
}).call(drag)
.on("dblclick", function(d) {
var index = points.indexOf(d);
console.log(index);
points.splice(index, 1);
d3.event.stopPropagation();
save();
draw();
})
}
var max = 10;
function scale(i) {
var offset = 1 * Math.tan(i/numSamples * 2 * Math.PI + tributary.t * Math.PI * 2);
//offset = Math.abs(offset)
if(offset > max) offset = max;
if(offset < -max) offset = -max;
return 0.836352 * Math.sin(3 * i/numSamples * 2 * Math.PI) + offset;
}
function save() {
setTimeout(function() {
var newpoints = [];
points.forEach(function(d) { newpoints.push(d) });
cm.setValue(JSON.stringify(newpoints));
}, 10)
}
draw();
tributary.run = function(g,t) {
draw();
}
function getSamples(path, num) {
var len = path.getTotalLength()
var p, t;
var result = []
for(var i = 0; i < num; i++) {
p = path.getPointAtLength(i * len/num);
t = getTangent(path, i/num * 100);
t.v.x *= vectorScale
t.v.y *= vectorScale
result.push({
point: p,
tangent: t,
perp: rotate2d(t.v, 90)
});
}
return result
}
function getTangent(path, percent) {
// returns a normalized vector that describes the tangent
// at the point that is found at *percent* of the path's length
var fraction = percent/100;
if(fraction < 0) fraction = 0;
if(fraction > 0.99) fraction = 1;
var len = path.getTotalLength();
var point1 = path.getPointAtLength(fraction * len - 0.1);
var point2 = path.getPointAtLength(fraction * len + 0.1);
var vector = { x: point2.x - point1.x, y: point2.y - point1.y }
var magnitude = Math.sqrt(vector.x*vector.x + vector.y*vector.y);
vector.x /= magnitude;
vector.y /= magnitude;
return {p: point1, v: vector };
}
function rotate2d(vector, angle) {
//rotate a vector
angle *= Math.PI/180; //convert to radians
return {
x: vector.x * Math.cos(angle) - vector.y * Math.sin(angle),
y: vector.x * Math.sin(angle) + vector.y * Math.cos(angle)
}
}
tributary.loop_type = "period"
[{"x":54,"y":316},{"x":262,"y":182},{"x":243,"y":433},{"x":70,"y":376},{"x":50,"y":469},{"x":396,"y":610},{"x":338,"y":248},{"x":564,"y":286},{"x":510,"y":538},{"x":602,"y":597},{"x":846,"y":620},{"x":627,"y":142},{"x":820,"y":284}]
#display {
background: white
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment