JSFiddle - React, Tailwind, and code Playground
by Scott Kaye
JavaScript
(function Rope() {
let clicks = 0;
let point1;
let canvas = document.createElement("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "absolute";
canvas.style.top = 0;
canvas.style.left = 0;
canvas.style.pointerEvents = "none";
document.body.appendChild(canvas);
let ctx = canvas.getContext("2d");
let pointGroups = [];
const numPoints = 10;
function clamp(i, min, max) {
return i >= min && i <= max ? i : i < min ? min : max;
}
function smoothThrough(points) {
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
let i;
for (i = 1; i < points.length - 2; ++i) {
let xc = (points[i].x + points[i + 1].x) / 2;
let 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);
}
class Point {
constructor(x, y, pin = false) {
this.x = x;
this.y = y;
this.pin = pin;
this.vx = 0;
this.vy = 0;
}
}
function createRope(fX, fY, tX, tY) {
let points = [new Point(fX, fY, true)];
let slopeX = (tX - fX) / numPoints;
let slopeY = (tY - fY) / numPoints;
let lastX = fX;
let lastY = fY;
for (let p = 0; p < numPoints; ++p) {
lastX += slopeX;
lastY += slopeY;
points.push(new Point(lastX, lastY));
}
points.push(new Point(tX, tY, true));
pointGroups.push(points);
}
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let g = 0; g < pointGroups.length; ++g) {
let points = pointGroups[g];
let last = points.length - 1;
ctx.beginPath();
ctx.ellipse(points[0].x, points[0].y, 5, 5, 0, 0, Math.PI * 2);
ctx.ellipse(points[last].x, points[last].y, 5, 5, 0, 0, Math.PI * 2);
ctx.fill();
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 -...