Edit in JSFiddle

/**
 * PhysicsJS by Jasper Palfree <wellcaffeinated.net>
 * http://wellcaffeinated.net/PhysicsJS
 *
 * Supermarket catastrophy
 */
Physics.behavior('demo-mouse-events', function (parent) {

    return {

        init: function (options) {

            var self = this;

            this.mousePos = Physics.vector();
            this.mousePosOld = Physics.vector();
            this.offset = Physics.vector();

            this.el = $(options.el).on({
                mousedown: function (e) {

                    var offset = $(this).offset();
                    self.mousePos.set(e.pageX - offset.left, e.pageY - offset.top);

                    var body = self._world.findOne({
                        $at: self.mousePos
                    });
                    if (body) {

                        // we're trying to grab a body

                        // fix the body in place
                        body.fixed = true;
                        // remember the currently grabbed body
                        self.body = body;
                        // remember the mouse offset
                        self.offset.clone(self.mousePos).vsub(body.state.pos);
                        return;
                    }

                    self.mouseDown = true;
                },
                mousemove: function (e) {
                    var offset = $(this).offset();
                    self.mousePosOld.clone(self.mousePos);
                    // get new mouse position
                    self.mousePos.set(e.pageX - offset.left, e.pageY - offset.top);
                },
                mouseup: function (e) {
                    var offset = $(this).offset();
                    self.mousePosOld.clone(self.mousePos);
                    self.mousePos.set(e.pageX - offset.left, e.pageY - offset.top);

                    // release the body
                    if (self.body) {
                        self.body.fixed = false;
                        self.body = false;
                    }
                    self.mouseDown = false;
                }
            });
        },

        connect: function (world) {

            // subscribe the .behave() method to the position integration step
            world.subscribe('integrate:positions', this.behave, this);
        },

        disconnect: function (world) {

            // unsubscribe when disconnected
            world.unsubscribe('integrate:positions', this.behave);
        },

        behave: function (data) {

            if (this.body) {

                // if we have a body, we need to move it the the new mouse position.
                // we'll also track the velocity of the mouse movement so that when it's released
                // the body can be "thrown"
                this.body.state.pos.clone(this.mousePos).vsub(this.offset);
                this.body.state.vel.clone(this.body.state.pos).vsub(this.mousePosOld).vadd(this.offset).mult(1 / 30);
                this.body.state.vel.clamp({
                    x: -1,
                    y: -1
                }, {
                    x: 1,
                    y: 1
                });
                return;
            }

            if (!this.mouseDown) {
                return;
            }

            // if we don't have a body, then just accelerate
            // all bodies towards the current mouse position

            var bodies = data.bodies
            // use a scratchpad to speed up calculations
            ,
                scratch = Physics.scratchpad(),
                v = scratch.vector(),
                body;

            for (var i = 0, l = bodies.length; i < l; ++i) {

                body = bodies[i];

                // simple linear acceleration law towards the mouse position
                v.clone(this.mousePos)
                    .vsub(body.state.pos)
                    .normalize()
                    .mult(0.001);

                body.accelerate(v);
            }

            scratch.done();
        }
    };
});

Physics(function (world) {

    var $win = $(window),
        viewWidth = $win.width(),
        viewHeight = 400,
        renderer = Physics.renderer('canvas', {
            el: 'viewport',
            width: viewWidth,
            height: viewHeight,
            meta: true,
            // debug:true,
            styles: {
                'circle': {
                    strokeStyle: 'hsla(60, 37%, 17%, 1)',
                    lineWidth: 1,
                    fillStyle: 'hsla(60, 37%, 57%, 0.8)',
                    angleIndicator: 'hsla(60, 37%, 17%, 0.4)'
                },
                    'convex-polygon': {
                    strokeStyle: 'hsla(60, 37%, 17%, 1)',
                    lineWidth: 1,
                    fillStyle: 'hsla(60, 47%, 37%, 0.8)',
                    angleIndicator: 'none'
                }
            }
        }),
        edgeBounce, rigidConstraints = Physics.behavior('rigid-constraint-manager', {
            targetLength: 8
        })
        // bounds of the window
        ,
        viewportBounds = Physics.aabb(0, 0, viewWidth, viewHeight);

    // add the renderer
    world.add(renderer);
    // render on each step
    world.subscribe('step', function () {
        world.render();
    });

    world.add(Physics.behavior('demo-mouse-events', {
        el: '#viewport'
    }));

    world.subscribe('integrate:positions', function () {

        var constraints = rigidConstraints.getConstraints(),
            c, threshold = 40,
            scratch = Physics.scratchpad(),
            v = scratch.vector(),
            len;

        for (var i = 0, l = constraints.length; i < l; ++i) {

            c = constraints[i];
            len = v.clone(c.bodyB.state.pos).vsub(c.bodyA.state.pos).norm();

            // break the constraint if above threshold
            if ((!c.bodyA.fixed && !c.bodyB.fixed) && (len - c.targetLength) > threshold) {

                rigidConstraints.remove(i);
            }
        }

        scratch.done();
        // higher priority than constraint resolution
    }, null, 100);

    // render
    world.subscribe('render', function (data) {

        var renderer = data.renderer,
            constraints = rigidConstraints.getConstraints(),
            c;

        for (var i = 0, l = constraints.length; i < l; ++i) {

            c = constraints[i];
            renderer.drawLine(c.bodyA.state.pos, c.bodyB.state.pos, 'hsla(60, 37%, 27%, 1)');
        }
    });


    // add gravity
    world.add(Physics.behavior('constant-acceleration'));

    world.pause();

    // subscribe to ticker to advance the simulation
    Physics.util.ticker.subscribe(function (time, dt) {

        world.step(time);
    });

    // start the ticker
    Physics.util.ticker.start();

    $(function () {
        // the "cloth"
        var cloth = [];
        for (var row = 0, l = 35; row < l; ++row) {
            for (var col = 0, lcol = 35; col < lcol; ++col) {

                cloth.push(
                Physics.body('circle', {
                    x: 8 * col + (viewWidth - l * 8) / 2,
                    y: 8 * row + 10,
                    radius: 4,
                    hidden: true
                }));

                if (col > 0) {
                    // horizontal
                    rigidConstraints.constrain(cloth[lcol * row + col - 1], cloth[lcol * row + col]);
                }

                if (row > 0) {

                    // vertical
                    rigidConstraints.constrain(cloth[lcol * row + col], cloth[lcol * (row - 1) + col]);
                } else {

                    cloth[lcol * row + col].fixed = true;
                }
            }
        }
        // add things to world
        world.add(cloth);
        world.add(rigidConstraints);
        world.unpause();
    });
});
<canvas id="viewport"></canvas>
html, body {
    background: #121212;
    margin: 0;
    height: 100%;
}
.pjs-meta {
    display: none;
}
#viewport {
    position: absolute;
    top:0;
    left: 0;
    bottom: 0;
    right: 0;
}