diff --git a/chain1.js b/chain1.js
new file mode 100644
index 0000000..181f9d7
--- /dev/null
+++ b/chain1.js
@@ -0,0 +1,47 @@
+let vec = p5.Vector
+
+class ConstraintPoint {
+ constructor(x, y, size) {
+ this.size = size;
+ this.pos = new vec(x, y);
+ this.forward = new vec(0, 0);
+ }
+
+ follow(targetX, targetY) {
+ let target = new vec(targetX, targetY);
+ let targetForward = vec.sub(target, this.pos);
+ let targetAngle = targetForward.heading();
+
+ this.forward = p5.Vector.fromAngle(targetAngle);
+
+ let dir = p5.Vector.mult(this.forward, -this.size);
+ this.pos = vec.add(target, dir);
+
+
+ }
+}
+
+let points = []
+function setup() {
+ createCanvas(400, 400);
+
+ for (let i = 0;i < 10;i++) {
+ points.push(new ConstraintPoint(0, 0, 20));
+ }
+}
+
+
+function draw() {
+ background(220);
+
+ points[0].follow(mouseX, mouseY)
+ for (let i = 1;i < 10;i++) {
+ let prev = points[i - 1];
+ points[i].follow(prev.pos.x, prev.pos.y);
+ }
+ for (let i = 1;i < 10;i++) {
+ let pos = points[i].pos;
+ noFill();
+ circle(pos.x, pos.y, 40);
+ }
+}
diff --git a/chain2.js b/chain2.js
new file mode 100644
index 0000000..c53aaa3
--- /dev/null
+++ b/chain2.js
@@ -0,0 +1,58 @@
+let vec = p5.Vector
+
+class ConstraintPoint {
+ constructor(x, y, size) {
+ this.size = size;
+ this.pos = new vec(x, y);
+ this.forward = new vec(0, 0);
+ }
+
+ follow(targetX, targetY, prevForward = null) {
+ let target = new vec(targetX, targetY);
+ let targetForward = vec.sub(target, this.pos);
+ let targetAngle = targetForward.heading();
+
+
+
+ if (prevForward) {
+ let a = targetAngle - prevForward;
+ while (a > PI) { a -= TWO_PI; }
+ while (a < -PI) { a += TWO_PI; }
+
+ a = constrain(a, -0.3, 0.3);
+
+ targetAngle = prevForward + a;
+ }
+
+ this.forward = vec.fromAngle(targetAngle);
+ let dir = vec.mult(this.forward, -this.size);
+ this.pos = vec.add(target, dir);
+
+
+ }
+}
+
+let points = []
+function setup() {
+ createCanvas(400, 400);
+
+ for (let i = 0;i < 10;i++) {
+ points.push(new ConstraintPoint(0, 0, 20));
+ }
+}
+
+
+function draw() {
+ background(220);
+
+ points[0].follow(mouseX, mouseY)
+ for (let i = 1;i < 10;i++) {
+ let prev = points[i - 1];
+ points[i].follow(prev.pos.x, prev.pos.y, prev.forward.heading());
+ }
+ for (let i = 0;i < 10;i++) {
+ let pos = points[i].pos;
+ noFill();
+ circle(pos.x, pos.y, 40);
+ }
+}
diff --git a/chain3.js b/chain3.js
new file mode 100644
index 0000000..28b0fe6
--- /dev/null
+++ b/chain3.js
@@ -0,0 +1,84 @@
+let vec = p5.Vector
+
+
+class ConstraintPoint {
+ constructor(x, y, size) {
+ this.size = size;
+ this.pos = new vec(x, y);
+ this.forward = new vec(0, 0);
+ }
+
+ follow(targetX, targetY, prevForward = null) {
+ let target = new vec(targetX, targetY);
+ let targetForward = vec.sub(target, this.pos);
+ let targetAngle = targetForward.heading();
+
+
+
+ if (prevForward) {
+ let a = targetAngle - prevForward;
+ while (a > PI) { a -= TWO_PI; }
+ while (a < -PI) { a += TWO_PI; }
+
+ a = constrain(a, -0.3, 0.3);
+
+ targetAngle = prevForward + a;
+ }
+
+ this.forward = vec.fromAngle(targetAngle);
+ let dir = vec.mult(this.forward, -this.size);
+ this.pos = vec.add(target, dir);
+ }
+
+ getRel(a, dist) {
+ return vec.add(this.pos, vec.mult(vec.fromAngle(this.forward.heading() + a), dist));
+ }
+}
+
+let points = []
+let sizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13]
+function setup() {
+ createCanvas(400, 400);
+
+ for (let i = 0;i < sizes.length;i++) {
+ points.push(new ConstraintPoint(0, 0, 20));
+ }
+}
+
+function drawPoints(points, sizes) {
+ beginShape();
+ for (let a = -HALF_PI;a < HALF_PI;a+=0.1) {
+ let p = points[0].getRel(a, sizes[0])
+ vertex(p.x, p.y);
+ }
+ for (let i = 0;i < points.length;i++) {
+ let p = points[i].getRel(HALF_PI, sizes[i])
+ vertex(p.x, p.y);
+ }
+
+ for (let a = HALF_PI;a < HALF_PI + PI;a+=0.1) {
+ let p = points[points.length -1].getRel(a, sizes[points.length -1])
+ vertex(p.x, p.y);
+ }
+
+ for (let i = points.length-1;i >= 0;i--) {
+ let p = points[i].getRel(-HALF_PI, sizes[i])
+ vertex(p.x, p.y);
+ }
+
+ endShape();
+}
+
+
+function draw() {
+ background(220);
+
+ points[0].follow(mouseX, mouseY)
+ for (let i = 1;i < sizes.length;i++) {
+ let prev = points[i - 1];
+ points[i].follow(prev.pos.x, prev.pos.y, prev.forward.heading());
+ }
+
+ fill(255)
+ drawPoints(points, sizes);
+}
diff --git a/index.html b/index.html
index 72fcde0..29549f6 100644
--- a/index.html
+++ b/index.html
@@ -4,11 +4,10 @@
-
Sketch
-
-
+ Procedural Animation
+
diff --git a/sketch.js b/sketch.js
index e023a06..a9791c5 100644
--- a/sketch.js
+++ b/sketch.js
@@ -41,8 +41,6 @@ class IKJoint {
let numPts = this.points.length;
this.points[0].size = 1;
this.points[0].follow(targetX, targetY);
- // this.points[0].pos.x = targetX;
- // this.points[0].pos.y = targetY;
for (let i = 1; i < numPts; i++) {
let prevPoint = this.points[i - 1];
@@ -110,24 +108,6 @@ class ConstraintPoint {
}
}
-let numPoints = 0;
-const bodySizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13];
-const legSizes = Array.from({ length: 20 }, () => 15);
-const bodyPoints = [];
-const leg1 = new Leg();
-const leg2 = new Leg();
-const leg3 = new Leg();
-const leg4 = new Leg();
-
-function setup() {
- createCanvas(800, 800);
- numPoints = bodySizes.length;
- for (let i = 0; i < numPoints; i++) {
- let pt = new ConstraintPoint(400, 400, 20);
- bodyPoints.push(pt);
- }
-}
-
function drawPoints(points, sizes) {
beginShape();
@@ -137,22 +117,22 @@ function drawPoints(points, sizes) {
for (let angle = -HALF_PI; angle <= HALF_PI; angle += PI / 10) {
let p = head.getRel(angle, sizes[0]);
- vertex(p.x, p.y);
+ curveVertex(p.x, p.y);
}
for (let i = 1; i < numPoints - 1; i++) {
let p = points[i].getRel(HALF_PI, sizes[i]);
- vertex(p.x, p.y);
+ curveVertex(p.x, p.y);
}
for (let angle = HALF_PI; angle <= HALF_PI + PI; angle += PI / 10) {
let p = tail.getRel(angle, sizes[numPoints - 1]);
- vertex(p.x, p.y);
+ curveVertex(p.x, p.y);
}
for (let i = numPoints - 2; i >= 1; i--) {
let p = points[i].getRel(-HALF_PI, sizes[i]);
- vertex(p.x, p.y);
+ curveVertex(p.x, p.y);
}
endShape(CLOSE);
@@ -161,7 +141,7 @@ function drawPoints(points, sizes) {
function drawGills(basePoint, sign) {
push();
- let p = basePoint.getRel(sign * 1.5* PI, 35);
+ let p = basePoint.getRel(sign * 1.5 * PI, 35);
translate(p.x, p.y);
rotate(basePoint.forward.heading() + 0.7 * sign);
@@ -189,17 +169,47 @@ function drawGills(basePoint, sign) {
pop();
}
+let numPoints = 0;
+const bodySizes = [60, 55, 50, 40, 45, 47, 50, 47, 45, 42, 39, 35, 30, 25, 22, 17, 13];
+const legSizes = Array.from({ length: 20 }, () => 15);
+const bodyPoints = [];
+const leg1 = new Leg();
+const leg2 = new Leg();
+const leg3 = new Leg();
+const leg4 = new Leg();
let mouseInter = new vec(0, 0);
+
+function setup() {
+ createCanvas(displayWidth, displayHeight);
+ numPoints = bodySizes.length;
+ for (let i = 0; i < numPoints; i++) {
+ let pt = new ConstraintPoint(400, 400, 20);
+ bodyPoints.push(pt);
+ }
+}
+
function draw() {
background(150);
- mouseInter.lerp(new vec(mouseX, mouseY), 0.1);
+ mouseInter.lerp(new vec(mouseX, mouseY), 0.01);
+ let time = millis();
// fisica
bodyPoints[0].follow(mouseInter.x, mouseInter.y);
+
for (let i = 1; i < numPoints; i++) {
let prevPoint = bodyPoints[i - 1];
bodyPoints[i].follow(prevPoint.pos.x, prevPoint.pos.y, prevPoint.forward);
+
+ let tailStart = Math.floor(numPoints / 2);
+ if (i > tailStart) {
+ let wiggleIntensity = map(i, tailStart, numPoints - 1, 0, 4);
+
+ let wiggleAmount = sin(time * 0.004 - i * 0.5) * wiggleIntensity;
+
+ let lateralDir = vec.rotate(bodyPoints[i].forward, HALF_PI);
+ bodyPoints[i].pos.add(p5.Vector.mult(lateralDir, wiggleAmount));
+ }
}
let legEndDist = 70;
let baseJointL1 = bodyPoints[2];
@@ -208,7 +218,7 @@ function draw() {
let baseR1 = baseJointL1.getRel(HALF_PI, 30);
let endR1 = baseJointL1.getRel(HALF_PI, legEndDist);
- let baseJointL2 = bodyPoints[7];
+ let baseJointL2 = bodyPoints[6];
let baseL2 = baseJointL2.getRel(-HALF_PI, 30);
let endL2 = baseJointL2.getRel(-HALF_PI, legEndDist);
let baseR2 = baseJointL2.getRel(HALF_PI, 30);
@@ -229,18 +239,27 @@ function draw() {
drawPoints(leg3.getPoints(), legSizes);
drawPoints(leg4.getPoints(), legSizes);
- drawPoints(bodyPoints, bodySizes);
+ let currentBodySizes = [...bodySizes];
+ let breathSpeed = time * 0.003;
+
+ for (let i = 0; i < numPoints; i++) {
+ let centerWeight = sin(map(i, 0, numPoints - 1, 0, PI));
+
+ let breathExpansion = sin(breathSpeed) * 1 * centerWeight + 1;
+ currentBodySizes[i] += breathExpansion;
+ }
+
+ drawPoints(bodyPoints, currentBodySizes);
let p1 = bodyPoints[4].pos;
let p2 = bodyPoints[6].pos;
let p3 = bodyPoints[8].pos;
let p4 = bodyPoints[10].pos;
push();
- // noStroke();
+ noStroke();
fill(243, 158, 189);
bezier(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
pop();
- // line(p1.x, p1.y, p4.x, p4.y);
drawGills(bodyPoints[2], 1);
drawGills(bodyPoints[2], -1);