mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Update MetaBalls example to be the same as that on Paperjs.org and convert to use the new notation style.
This commit is contained in:
parent
e692bf4c74
commit
ba33fd6ebf
1 changed files with 91 additions and 76 deletions
|
@ -12,44 +12,50 @@
|
||||||
fillColor: 'black'
|
fillColor: 'black'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var ballPositions = [[255, 129], [610, 73], [486, 363],
|
||||||
|
[117, 459], [484, 726], [843, 306], [789, 615], [1049, 82],
|
||||||
|
[1292, 428], [1117, 733], [1352, 86], [92, 798]];
|
||||||
|
|
||||||
var handle_len_rate = 2.4;
|
var handle_len_rate = 2.4;
|
||||||
var circlePaths = [];
|
var circlePaths = [];
|
||||||
var circlePath;
|
|
||||||
var radius = 50;
|
var radius = 50;
|
||||||
circlePaths.push(new Path.Circle(view.center, 100));
|
for (var i = 0, l = ballPositions.length; i < l; i++) {
|
||||||
function onMouseDown(event) {
|
var circlePath = new Path.Circle({
|
||||||
circlePath = null;
|
center: ballPositions[i],
|
||||||
for (var i = 0, l = circlePaths.length; i < l; i++) {
|
radius: 50
|
||||||
var path = circlePaths[i];
|
});
|
||||||
if (path.position.getDistance(event.point) < 50)
|
|
||||||
circlePath = path;
|
|
||||||
}
|
|
||||||
if (!circlePath) {
|
|
||||||
circlePath = new Path.Circle(event.point, 50);
|
|
||||||
circlePaths.push(circlePath);
|
circlePaths.push(circlePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var largeCircle = new Path.Circle({
|
||||||
|
center: [676, 433],
|
||||||
|
radius: 100
|
||||||
|
});
|
||||||
|
circlePaths.push(largeCircle);
|
||||||
|
|
||||||
|
function onMouseMove(event) {
|
||||||
|
largeCircle.position = event.point;
|
||||||
generateConnections(circlePaths);
|
generateConnections(circlePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseDrag(event) {
|
var connections = new Group();
|
||||||
circlePath.position = event.point;
|
|
||||||
generateConnections(circlePaths);
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateConnections(paths) {
|
function generateConnections(paths) {
|
||||||
|
// Remove the last connection paths:
|
||||||
|
connections.children = [];
|
||||||
|
|
||||||
for (var i = 0, l = paths.length; i < l; i++) {
|
for (var i = 0, l = paths.length; i < l; i++) {
|
||||||
for (var j = i - 1; j >= 0; j--) {
|
for (var j = i - 1; j >= 0; j--) {
|
||||||
var path = metaball(paths[i], paths[j], 0.5, handle_len_rate, 300);
|
var path = metaball(paths[i], paths[j], 0.5, handle_len_rate, 300);
|
||||||
if (path) {
|
if (path) {
|
||||||
path.removeOn({
|
connections.appendTop(path);
|
||||||
drag: true,
|
path.removeOnMove();
|
||||||
down: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateConnections(circlePaths);
|
||||||
|
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
function metaball(ball1, ball2, v, handle_len_rate, maxDistance) {
|
function metaball(ball1, ball2, v, handle_len_rate, maxDistance) {
|
||||||
var center1 = ball1.position;
|
var center1 = ball1.position;
|
||||||
|
@ -66,8 +72,10 @@
|
||||||
if (d > maxDistance || d <= Math.abs(radius1 - radius2)) {
|
if (d > maxDistance || d <= Math.abs(radius1 - radius2)) {
|
||||||
return;
|
return;
|
||||||
} else if (d < radius1 + radius2) { // case circles are overlapping
|
} else if (d < radius1 + radius2) { // case circles are overlapping
|
||||||
u1 = Math.acos((radius1 * radius1 + d * d - radius2 * radius2) / (2 * radius1 * d));
|
u1 = Math.acos((radius1 * radius1 + d * d - radius2 * radius2) /
|
||||||
u2 = Math.acos((radius2 * radius2 + d * d - radius1 * radius1) / (2 * radius2 * d));
|
(2 * radius1 * d));
|
||||||
|
u2 = Math.acos((radius2 * radius2 + d * d - radius1 * radius1) /
|
||||||
|
(2 * radius2 * d));
|
||||||
} else {
|
} else {
|
||||||
u1 = 0;
|
u1 = 0;
|
||||||
u2 = 0;
|
u2 = 0;
|
||||||
|
@ -83,16 +91,23 @@
|
||||||
var p1b = center1 + getVector(angle1b, radius1);
|
var p1b = center1 + getVector(angle1b, radius1);
|
||||||
var p2a = center2 + getVector(angle2a, radius2);
|
var p2a = center2 + getVector(angle2a, radius2);
|
||||||
var p2b = center2 + getVector(angle2b, radius2);
|
var p2b = center2 + getVector(angle2b, radius2);
|
||||||
// define handle length by the distance between both ends of the curve to draw
|
|
||||||
var d2 = Math.min(v * handle_len_rate, p1a.getDistance(p2a) / (radius1 + radius2));
|
|
||||||
|
|
||||||
d2 *= Math.min(1, d * 2 / (radius1 + radius2)); // case circles are overlapping
|
// define handle length by the distance between
|
||||||
|
// both ends of the curve to draw
|
||||||
|
var totalRadius = (radius1 + radius2);
|
||||||
|
var d2 = Math.min(v * handle_len_rate, (p1a - p2a).length / totalRadius);
|
||||||
|
|
||||||
|
// case circles are overlapping:
|
||||||
|
d2 *= Math.min(1, d * 2 / (radius1 + radius2));
|
||||||
|
|
||||||
radius1 *= d2;
|
radius1 *= d2;
|
||||||
radius2 *= d2;
|
radius2 *= d2;
|
||||||
|
|
||||||
var path = new Path([p1a, p2a, p2b, p1b]);
|
var path = new Path({
|
||||||
path.style = ball1.style;
|
segments: [p1a, p2a, p2b, p1b],
|
||||||
path.closed = true;
|
style: ball1.style,
|
||||||
|
closed: true
|
||||||
|
});
|
||||||
var segments = path.segments;
|
var segments = path.segments;
|
||||||
segments[0].handleOut = getVector(angle1a - pi2, radius1);
|
segments[0].handleOut = getVector(angle1a - pi2, radius1);
|
||||||
segments[1].handleIn = getVector(angle2a + pi2, radius2);
|
segments[1].handleIn = getVector(angle2a + pi2, radius2);
|
||||||
|
|
Loading…
Reference in a new issue