Here is the interesting part of the computation:
function Fabric( canvas, settings )
{
var _canvas = canvas;
var _width = canvas.width;
var _height = canvas.height;
var _mousePos = new Point( 0, 0 );
var _entities = [];
var _constraints = [];
function init()
{
_entities = [];
_constraints = [];
var origin = _settings.origin;
var width = _settings.clothWidth;
var height = _settings.clothHeight;
var segments = _settings.segments;
var e = _settings.strength;
var xStride = width / segments;
var yStride = height / segments;
var cols = segments + 1;
for( var y = 0; y <= segments; ++y )
{
for( var x = 0; x <= segments; ++x )
{
var px = origin.x + x * xStride;
var py = origin.y + y * yStride;
_entities.push( new Entity( px, py ) );
var i = y * cols + x;
if( x > 0 )
{
_constraints.push( new DistanceConstraint( _entities[ i ], _entities[ i - 1 ], e ) );
}
if( y > 0 )
{
_constraints.push( new DistanceConstraint( _entities[ i ], _entities[ ( y - 1 ) * cols + x ], e ) );
}
if( y == 0 && x % 5 == 0 )
{
_constraints.push( new EdgeConstraint( _entities[ i ] ) );
}
}
}
}
this.step = function()
{
for( var i = 0, n = _entities.length; i < n; ++i )
{
var p = _entities[ i ];
var vx = ( p.x - p.lastX ) * _settings.elasticity;
var vy = ( p.y - p.lastY ) * _settings.elasticity;
p.lastX = p.x;
p.lastY = p.y;
p.x += vx;
p.y += vy;
p.x += _settings.gravity.x;
p.y += _settings.gravity.y;
}
for( var j = 0; j < 20; ++j )
{
for( var k = 0; k < _constraints.length; ++k )
{
_constraints[ k ].step();
}
}
};
}
function DistanceConstraint( entityA, entityB, strength )
{
this.a = entityA;
this.b = entityB;
this.strength = strength;
var dx = entityA.x - entityB.x;
var dy = entityA.y - entityB.y;
this.distance = Math.sqrt( dx * dx + dy * dy );
this.step = function()
{
var nx = this.a.x - this.b.x;
var ny = this.a.y - this.b.y;
var m = ( nx * nx + ny * ny );
var s = ( ( this.distance * this.distance - m ) / m ) * this.strength;
nx *= s;
ny *= s;
this.a.x += nx;
this.a.y += ny;
this.b.x -= nx;
this.b.y -= ny;
};
}
function EdgeConstraint( entity )
{
this.a = entity;
this.x = entity.x;
this.y = entity.y;
this.step = function()
{
this.a.x = this.x;
this.a.y = this.y;
};
}