Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created September 4, 2013 05:06
Show Gist options
  • Save enjalot/6432958 to your computer and use it in GitHub Desktop.
Save enjalot/6432958 to your computer and use it in GitHub Desktop.
blobular
{"editor_editor":{"coffee":false,"vim":true,"emacs":false,"width":528,"height":680,"hide":false},"description":"blobular","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"loop":true,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/U2cDnmV.png","inline-console":false}
//trying to recreate the effect from here:
//www.themaninblue.com/experiment/Blobular/
var a = {
x: 200,
y: 200,
r: 129
};
var b = {
x: tributary.anim(395, 270),
y: 300,
r: 88
};
var join = {
r: 62
};
var originDistance = a.r - b.r;
console.log(originDistance);
a.area = Math.PI * Math.pow(a.r, 2);
b.area = Math.PI * Math.pow(b.r, 2);
var afterCircleArea = a.area - b.area;
console.log("a area",a.area, "b area", b.area, "diff", afterCircleArea);
var distance = calculateDistance(a,b);
var distanceDiff = distance - originDistance;
if(distanceDiff < 1) { distanceDiff = 1 }
var dontdraw = false;
if(distance > 2*join.r + a.r + b.r) {
console.log("MAY DAY");
dontdraw = true;
}
var angle = calculateAngle(a,b);
b.h = 0;
b.k = 0 - a.r + b.r - distanceDiff;
//console.log(b.k, join.r)
var triangleA = a.r + join.r; // Side a
var triangleB = b.r + join.r; // Side b
var triangleC = Math.abs(b.k - 0); // Side c
var triangleP = (triangleA + triangleB + triangleC) / 2; // Triangle half perimeter
var triangleArea = Math.sqrt(triangleP * (triangleP - triangleA) * (triangleP - triangleB) * (triangleP - triangleC)); // Triangle area
if (triangleC >= triangleA)
{
var triangleH = 2 * triangleArea / triangleC; // Triangle height
var triangleD = Math.sqrt(Math.pow(triangleA, 2) - Math.pow(triangleH, 2)); // Big circle bisection of triangleC
}
else
{
var triangleH = 2 * triangleArea / triangleA; // Triangle height
var triangleD = Math.sqrt(Math.pow(triangleC, 2) - Math.pow(triangleH, 2)); // Small circle bisection of triangleA
}
a.tan = triangleH / triangleD;
a.angle = Math.atan(a.tan);
a.sin = Math.sin(a.angle);
a.intersectX = a.sin * a.r;
a.cos = Math.cos(a.angle);
a.intersectY = a.cos * a.r;
console.log(a)
join.x = 0 + a.sin * (a.r + join.r);
join.y = 0 - a.cos * (a.r + join.r);
var coord1 = {
x: -a.intersectX,
y: -a.intersectY
};
var coord2 = {
x: a.intersectX,
y: -a.intersectY
}
b.tan = (b.k - join.y) / (b.h - join.x);
b.angle = Math.atan(b.tan);
b.intersectX = join.x - Math.cos(b.angle) * (join.r);
b.intersectY = join.y - Math.sin(b.angle) * (join.r);
console.log(b)
var lavaPathD = "M " + coord1.x + " " + coord1.y + " A " + a.r + " " + a.r + " 0 1 0 " + coord2.x + " " + coord2.y;
console.log(lavaPathD);
if (join.x - join.r <= 0 && b.k < join.y)
{
var crossOverY = circleYFromX(join, 0);
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 0 " + (join.y + crossOverY);
lavaPathD += "m 0 -" + (crossOverY * 2);
}
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + b.intersectX + " " + b.intersectY;
console.log(lavaPathD);
var largeArcFlag = 1;
if (join.y < b.k)
{
largeArcFlag = 0;
}
lavaPathD += "a " + b.r + " " + b.r + " 0 " + largeArcFlag + " 0 " + (b.intersectX * -2) + " 0";
console.log(lavaPathD);
if (join.x - join.r <= 0 && b.k < join.y)
{
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 0 " + (join.y - crossOverY);
lavaPathD += "m 0 " + (crossOverY * 2);
}
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + coord1.x + " " + coord1.y;
console.log(lavaPathD);
lavaPathD += "A " + join.r + " " + join.r + " 0 0 1 " + coord1.x + " " + coord1.y;
console.log(lavaPathD);
var data = [a,b];
var cs = d3.scale.category10();
var svg = d3.select("svg");
var sel = svg.selectAll("circle.blob")
.data(data)
.enter()
.append("circle")
.classed("blob", true)
.attr("cx", function(d) { return d.x })
.attr("cy", function(d) {return d.y })
.attr("r", function(d) { return d.r })
.style("fill", function(d,i) { return cs(i); })
.style("fill-opacity", 0.5)
.style("stroke", function(d,i) { return cs(i); })
if(!dontdraw) {
var lavaPath = svg.append("path")
.classed("lava", true)
.attr("transform", function() {
var translate = "translate(" + [a.x, a.y] + ")";
var rotate = "rotate(" + [angle, 0, 0] + ")";
return translate + rotate;
})
.style("fill", "none")
.style("stroke", "#000")
.style("stroke-width", 2)
.attr("d", lavaPathD)
}
function calculateDistance(origin, point) {
var xx = point.x - origin.x;
var yy = point.y - origin.y;
return Math.sqrt(xx*xx + yy*yy)
}
function calculateAngle(origin, point)
{
var tan = (point.y - origin.y) / (point.x - origin.x);
var angle = Math.atan(tan) / Math.PI * 180 + 90;
if (point.x < origin.x)
{
angle += 180;
}
return angle;
}
function circleYFromX (circle, x)
{
return Math.sqrt(Math.pow(circle.r, 2) - Math.pow(x - circle.x, 2));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment