JSFiddle - React, Tailwind, and code Playground
by Scott Kaye
HTML
<canvas id="c"></canvas>
JavaScript
let canvas = document.getElementById("c");
let ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
ctx.width = 500;
ctx.height = 500;
class Point {
constructor(pin = false) {
let x = Math.random() * 40 + 50;
let y = Math.random() * 40 + 50;
this.x = x;
this.y = y;
this.pin = pin;
this.vx = 0;
this.vy = 0;
}
}
let numPoints = 10;
let points = [new Point(true)];
for(let p=0;p<numPoints;++p)points.push(new Point());
function smoothThrough(points) {
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
let i;
for (i = 1; i < points.length - 2; ++i) {
var xc = (points[i].x + points[i + 1].x) / 2;
var yc = (points[i].y + points[i + 1].y) / 2;
ctx.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
}
ctx.quadraticCurveTo(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y);
}
function clamp(i, min, max) {
return i >= min && i <= max ? i : i < min ? min : max;
}
function update() {
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < points.length; ++i) {
// Debug:
ctx.fillStyle = "#f00";
ctx.fillRect(points[i].x - 2, points[i].y - 2, 4, 4);
if (points[i - 1]) {
let diffX = points[i - 1].x - points[i].x;
let diffY = points[i - 1].y - points[i].y;
let d = Math.sqrt(diffX * diffX + diffY * diffY);
let diff = ((numPoints / canvas.width) - d) / d;
let tX = diffX * 0.35 * diff;
let tY = diffY * 0.35 * diff;
if (!points[i].pin) {
points[i].vx -= tX;
points[i].vy -= tY;
}
if (!points[i - 1].pin) {
points[i - 1].vx += tX;
points[i - 1].vy += tY;
}
}
if (!points[i].pin) {
// Inertia
points[i].vx = clamp(points[i].vx, -15, 15);
points[i].vy = clamp(points[i].vy, -15, 15);
points[i].x += points[i].vx;
points[i].y += points[i].vy;
points[i].vx *= 0.85;
points[i].vy *= 0.85;
...