Skip to content

Instantly share code, notes, and snippets.

@stephanbogner
Last active July 23, 2017 11:47
Show Gist options
  • Select an option

  • Save stephanbogner/bd96b24bfea82e7d2b6531060e386d59 to your computer and use it in GitHub Desktop.

Select an option

Save stephanbogner/bd96b24bfea82e7d2b6531060e386d59 to your computer and use it in GitHub Desktop.
Joint between two particles (verlet integration)
<canvas id="myCanvas" width="600" height="400"></canvas>
<style type="text/css">
canvas {
background: #F9F9F9;
margin: 3rem auto;
display: block;
}
</style>
<script>
var point1, point2, canvas, context, fps, interval, cursorX, cursorY;
init();
function init() {
// Set the start coordinates of our points
point1 = {
"x": 150,
"y": 170
}
point2 = {
"x": 250,
"y": 180
}
// Reference canvas
canvas = document.getElementById('myCanvas');
context = canvas.getContext('2d');
fps = 30;
interval = 1 / fps * 1000; // 30 fps = doing something every (1/fps*1000) ms
cursorX = 0; // start position of cursor (before we get the mouse position)
cursorY = 0;
initMouseListener();
setInterval(function() { update(); }, interval); // Draw 30 times per second
}
function update() {
clearCanvas(); // Clear canvas
setPointCoordinates(point1, { "x": cursorX, "y": cursorY }); // Move point to position of cursor
constraint(point1, point2, 100); // Move point 1 and 2 so their distance equals exactly 100 pixels
drawLine(point1, point2); // Draw line between point 1 and 2
drawPoint(point1); // Draw point 1
drawPoint(point2); // Draw point 2
}
function constraint(point1, point2, targetDistance) {
var fraction = 0.8; // This dampens the movement (1 = instant movement, 0 is no movement, 0.5 is a wobbly movement)
var dx = point1.x - point2.x; // Distance between coordinates in x direction
var dy = point1.y - point2.y; // Distance between coordinates in y direction
var currentDistance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); // Distance between Point 1 and Point 2 (pythagoras)
var distanceDifference = targetDistance - currentDistance; // How far the points should be apart vs how far are they apart
var angle = -Math.atan2(dx, dy); // Angle between points
var moveX = Math.sin(angle) * distanceDifference; // Move much do you have to push a point in x direction
var moveY = Math.cos(angle) * distanceDifference; // Move much do you have to push a point in y direction
// Push points (divided by 2 because we want to push both ends and fraction for bouncy movement)
point1.x -= moveX * fraction / 2;
point1.y += moveY * fraction / 2;
point2.x += moveX * fraction / 2;
point2.y -= moveY * fraction / 2;
}
function drawPoint(point) {
var radius = 10;
context.beginPath();
context.arc(point.x, point.y, radius, 0, 2 * Math.PI, false);
context.fillStyle = '#0000FF';
context.fill();
}
function drawLine(point1, point2) {
context.beginPath();
context.lineWidth = 4;
context.strokeStyle = '#C3C3F9';
context.moveTo(point1.x, point1.y);
context.lineTo(point2.x, point2.y);
context.stroke();
}
function setPointCoordinates(point, newCoordinates) {
point.x = newCoordinates.x;
point.y = newCoordinates.y;
}
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
function initMouseListener() {
document.getElementById('myCanvas').onmousemove = function(e) {
cursorX = e.pageX - this.offsetLeft
cursorY = e.pageY - this.offsetTop
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment