Ragdolls | Verlet Integration
How do I make an ragdolls | verlet integration?
Some more Verlet Integration...All my verlet integration Pens. What is a ragdolls | verlet integration? How do you make a ragdolls | verlet integration? This script and codes were developed by Johan Karlsson on 26 July 2022, Tuesday.
Ragdolls | Verlet Integration - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Ragdolls | Verlet Integration</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <canvas id="canvas"></canvas>
<h3 id="instructions"> Drag a ragdoll and throw it around! <button id="jump"><b>Jump!</b></button>
</h3> <script src="js/index.js"></script>
</body>
</html>
Ragdolls | Verlet Integration - Script Codes CSS Codes
@import url(https://fonts.googleapis.com/css?family=Noto+Sans);
* { font-family: 'Noto Sans', sans-serif;
}
body, html { margin: 0;
}
canvas { display: block;
}
#instructions { position: fixed; top: 0; margin-left: 20px;
}
Ragdolls | Verlet Integration - Script Codes JS Codes
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/* Johan Karlsson, DonKarlssonSan Verlet Integration from Coding Math by Keith Peters. My Verlet Integration Pens: http://codepen.io/collection/DxeyOb/
*/
function distance(p0, p1) { var x = p1.x - p0.x; var y = p1.y - p0.y; return Math.sqrt(x * x + y * y);
}
var Point = function Point(x, y, extremity, gravity, radius) { _classCallCheck(this, Point); this.x = x; this.y = y; this.oldx = x; this.oldy = y; this.extremity = extremity; if (extremity) { this.r = 5; } else { this.r = radius || 1; } this.g = gravity || 0.1;
};
var Stick = function Stick(p0, p1, invisible) { _classCallCheck(this, Stick); this.p0 = p0; this.p1 = p1; this.length = distance(p0, p1); this.invisible = invisible;
};
var World = function () { function World() { var _this = this; _classCallCheck(this, World); this.canvas = document.getElementById("canvas"); this.ctx = canvas.getContext("2d"); this.h = this.canvas.height = window.innerHeight; this.w = this.canvas.width = window.innerWidth; this.ctx.lineWidth = 2; this.bounce = 0.65; this.friction = 0.994; this.points = []; this.sticks = []; this.createRagdoll(100, 0); this.createRagdoll(300, 0); this.isDragging = false; this.dragPoint = undefined; this.canvas.addEventListener("mousedown", function (event) { return _this.onMouseDown(event); }); this.onMouseMove = this.onMouseMove.bind(this); this.onMouseUp = this.onMouseUp.bind(this); document.getElementById("jump").addEventListener("click", function () { return _this.onJumpClick(); }); } World.prototype.createRagdoll = function createRagdoll(x0, y0) { // Start index var i0 = this.points.length; // Head var h = new Point(x0, y0, false, 0.12, 15); h.head = true; h.oldx = x0 + (Math.random() - 0.5) * 25; this.points.push(h); // Groin this.points.push(new Point(x0, y0 + 80, false, 0.15)); // Hips this.points.push(new Point(x0 + 15, y0 + 90, false, 0.12)); this.points.push(new Point(x0 - 15, y0 + 90, false, 0.12)); // Knees this.points.push(new Point(x0 + 20, y0 + 130)); this.points.push(new Point(x0 - 20, y0 + 130)); // Feet this.points.push(new Point(x0 + 20, y0 + 180, true)); this.points.push(new Point(x0 - 20, y0 + 180, true)); // Neck this.points.push(new Point(x0, y0 + 25)); // Shoulders this.points.push(new Point(x0 + 15, y0 + 25)); this.points.push(new Point(x0 - 15, y0 + 25)); // Hands this.points.push(new Point(x0 + 15, y0 + 105, true)); this.points.push(new Point(x0 - 15, y0 + 105, true)); // "Muscles" // Head - shoulders this.sticks.push(new Stick(this.points[i0], this.points[i0 + 9], true)); this.sticks.push(new Stick(this.points[i0], this.points[i0 + 10], true)); // Shoulder - shoulder this.sticks.push(new Stick(this.points[i0 + 9], this.points[i0 + 10], true)); // Shoulders - hips this.sticks.push(new Stick(this.points[i0 + 9], this.points[i0 + 2], true)); this.sticks.push(new Stick(this.points[i0 + 10], this.points[i0 + 3], true)); // Shoulders - hips opposite side this.sticks.push(new Stick(this.points[i0 + 9], this.points[i0 + 3], true)); this.sticks.push(new Stick(this.points[i0 + 10], this.points[i0 + 2], true)); // Hips - feet this.sticks.push(new Stick(this.points[i0 + 2], this.points[i0 + 6], true)); this.sticks.push(new Stick(this.points[i0 + 3], this.points[i0 + 7], true)); // Hips - feet, opposite this.sticks.push(new Stick(this.points[i0 + 2], this.points[i0 + 7], true)); this.sticks.push(new Stick(this.points[i0 + 3], this.points[i0 + 6], true)); // Head - groin this.sticks.push(new Stick(this.points[i0], this.points[i0 + 1], true)); // Hip - hip this.sticks.push(new Stick(this.points[i0 + 2], this.points[i0 + 3], true)); // Shoulder - hip this.sticks.push(new Stick(this.points[i0 + 9], this.points[i0 + 2], true)); this.sticks.push(new Stick(this.points[i0 + 10], this.points[i0 + 3], true)); // Head - knee this.sticks.push(new Stick(this.points[i0], this.points[i0 + 4], true)); // Head - knee this.sticks.push(new Stick(this.points[i0], this.points[i0 + 5], true)); // Head feet this.sticks.push(new Stick(this.points[i0], this.points[i0 + 6], true)); this.sticks.push(new Stick(this.points[i0], this.points[i0 + 7], true)); // Body parts // Hips this.sticks.push(new Stick(this.points[i0 + 1], this.points[i0 + 2])); this.sticks.push(new Stick(this.points[i0 + 1], this.points[i0 + 3])); // Legs this.sticks.push(new Stick(this.points[i0 + 2], this.points[i0 + 4])); this.sticks.push(new Stick(this.points[i0 + 3], this.points[i0 + 5])); this.sticks.push(new Stick(this.points[i0 + 4], this.points[i0 + 6])); this.sticks.push(new Stick(this.points[i0 + 5], this.points[i0 + 7])); this.sticks.push(new Stick(this.points[i0], this.points[i0 + 8])); this.sticks.push(new Stick(this.points[i0 + 8], this.points[i0 + 1])); // Left arm this.sticks.push(new Stick(this.points[i0 + 8], this.points[i0 + 9])); this.sticks.push(new Stick(this.points[i0 + 9], this.points[i0 + 11])); // Right arm this.sticks.push(new Stick(this.points[i0 + 8], this.points[i0 + 10])); this.sticks.push(new Stick(this.points[i0 + 10], this.points[i0 + 12])); }; World.prototype.onJumpClick = function onJumpClick() { var p = this.points[0]; p.oldy = p.y + 50; }; World.prototype.onMouseDown = function onMouseDown(event) { var x = event.clientX; var y = event.clientY; var p0 = { x: x, y: y }; var p1 = this.getClosestPoint(p0); var dist = this.distance(p0, p1); if (dist < 30) { this.dragPoint = p1; this.dragPoint.x = x; this.dragPoint.y = y; this.dragPoint.oldx = x; this.dragPoint.oldy = y; this.dragPoint.pinned = true; this.isDragging = true; this.canvas.addEventListener("mousemove", this.onMouseMove); this.canvas.addEventListener("mouseup", this.onMouseUp); } }; World.prototype.onMouseMove = function onMouseMove(event) { this.dragPoint.oldx = this.dragPoint.x; this.dragPoint.oldy = this.dragPoint.y; this.dragPoint.x = event.clientX; this.dragPoint.y = event.clientY; }; World.prototype.onMouseUp = function onMouseUp(event) { this.dragPoint.pinned = false; this.isDragging = false; this.canvas.removeEventListener("mousemove", this.onMouseMove); this.canvas.removeEventListener("mouseup", this.onMouseUp); }; World.prototype.getClosestPoint = function getClosestPoint(p0) { var _this2 = this; var index = 0; this.points.map(function (p1) { return _this2.distance(p0, p1); }).reduce(function (prev, curr, i) { if (curr < prev) { index = i; } return Math.min(curr, prev); }); return this.points[index]; }; World.prototype.distance = function distance(p0, p1) { var x = p1.x - p0.x; var y = p1.y - p0.y; return Math.sqrt(x * x + y * y); }; World.prototype.update = function update() { //this.ctx.clearRect(0, 0, this.w, this.h); this.ctx.fillStyle = "white"; this.ctx.fillRect(0, 0, this.w, this.h); this.updatePoints(); this.updateSticks(); this.drawSticks(); this.drawHeads(); this.drawExtremities(); }; World.prototype.drawHeads = function drawHeads() { var _this3 = this; this.ctx.fillStyle = "black"; this.points.filter(function (p) { return p.head; }).forEach(function (h) { _this3.ctx.beginPath(); _this3.ctx.arc(h.x, h.y, h.r, 0, Math.PI * 2); _this3.ctx.fill(); }); }; World.prototype.drawExtremities = function drawExtremities() { var _this4 = this; this.ctx.fillStyle = "black"; this.points.filter(function (p) { return p.extremity; }).forEach(function (e) { _this4.ctx.beginPath(); _this4.ctx.arc(e.x, e.y, e.r, 0, Math.PI * 2); _this4.ctx.fill(); }); }; World.prototype.drawSticks = function drawSticks() { var _this5 = this; this.sticks.forEach(function (s) { _this5.ctx.beginPath(); if (s.invisible) { _this5.ctx.strokeStyle = "rgba(255, 0, 0, 0.2)"; } else { _this5.ctx.strokeStyle = "black"; } _this5.ctx.moveTo(s.p0.x, s.p0.y); _this5.ctx.lineTo(s.p1.x, s.p1.y); _this5.ctx.stroke(); }); }; World.prototype.updatePoints = function updatePoints() { var _this6 = this; this.points.forEach(function (p) { if (!p.pinned) { var vx = (p.x - p.oldx) * _this6.friction; var vy = (p.y - p.oldy) * _this6.friction; p.oldx = p.x; p.oldy = p.y; // Ground friction if (p.y + p.r > _this6.h - 1) { vx = 0; } p.x += vx; p.y += vy; p.y += p.g; if (p.x + p.r > _this6.w) { p.x = _this6.w - p.r; p.oldx = p.x + vx * _this6.bounce; } if (p.x - p.r < 0) { p.x = p.r; p.oldx = p.x + vx * _this6.bounce; } if (p.y + p.r > _this6.h) { p.y = _this6.h - p.r; p.oldy = p.y + vy * _this6.bounce; } if (p.y - p.r < 0) { p.y = p.r; p.oldy = p.y + vy * _this6.bounce; } } }); }; World.prototype.updateSticks = function updateSticks() { this.sticks.forEach(function (s) { var dx = s.p1.x - s.p0.x; var dy = s.p1.y - s.p0.y; var dist = Math.sqrt(dx * dx + dy * dy); var diff = s.length - dist; var percent = diff / dist / 2; if (s.invisible) { // This is a "muscle", it should be // more elastic than the bones. percent /= 3; } var offsetX = dx * percent; var offsetY = dy * percent; if (!s.p0.pinned) { s.p0.x -= offsetX; s.p0.y -= offsetY; } if (!s.p1.pinned) { s.p1.x += offsetX; s.p1.y += offsetY; } }); }; return World;
}();
var world = new World();
function animate() { world.update(); requestAnimationFrame(animate);
}
animate();
Developer | Johan Karlsson |
Username | DonKarlssonSan |
Uploaded | July 26, 2022 |
Rating | 4.5 |
Size | 6,479 Kb |
Views | 38,456 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Cash by Brownian Motion | 3,530 Kb |
Random Fractal | 2,751 Kb |
Circle Fractal | 2,482 Kb |
Particle Text | 5,685 Kb |
Portrait by Brownian Motion | 3,612 Kb |
Photobooth - Webcam with realtime CSS filters. | 4,390 Kb |
Text by Brownian Motion | 3,182 Kb |
Laser Writer | 6,065 Kb |
Rotating Neon Curves | 3,770 Kb |
Phone Case Pattern Animation | 2,774 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Jquery 2d character movement | Drewtadams | 4,291 Kb |
Process Accordion | Devilskitchen | 31,432 Kb |
Growing Root - Scroll control - CANVAS | Cjonasw | 2,342 Kb |
A Pen by Alexandru Pora | Axpro | 1,615 Kb |
Blog | Rottingroom | 1,430 Kb |
A Pen by Paul Sullivan | Pwsm50 | 2,349 Kb |
SVG Circle Progress | JMChristensen | 3,368 Kb |
Pure CSS Dial | Lukewatts | 3,018 Kb |
React JS Movie Info App | MTushar | 4,870 Kb |
Delete Hover | Chungman93 | 2,557 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!