UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

262 lines (227 loc) 8.46 kB
/** * The `Matter.MouseConstraint` module contains methods for creating mouse constraints. * Mouse constraints are used for allowing user interaction, providing the ability to move bodies via the mouse or touch. * * See the included usage [examples](https://github.com/liabru/matter-js/tree/master/examples). * * @class MouseConstraint */ var MouseConstraint = {}; module.exports = MouseConstraint; var Vertices = require('../geometry/Vertices'); var Sleeping = require('../core/Sleeping'); var Mouse = require('../core/Mouse'); var Events = require('../core/Events'); var Detector = require('../collision/Detector'); var Constraint = require('./Constraint'); var Composite = require('../body/Composite'); var Common = require('../core/Common'); var Bounds = require('../geometry/Bounds'); (function() { /** * Creates a new mouse constraint. * All properties have default values, and many are pre-calculated automatically based on other properties. * See the properties section below for detailed information on what you can pass via the `options` object. * @method create * @param {engine} engine * @param {} options * @return {MouseConstraint} A new MouseConstraint */ MouseConstraint.create = function(engine, options) { var mouse = (engine ? engine.mouse : null) || (options ? options.mouse : null); if (!mouse) { if (engine && engine.render && engine.render.canvas) { mouse = Mouse.create(engine.render.canvas); } else if (options && options.element) { mouse = Mouse.create(options.element); } else { mouse = Mouse.create(); Common.warn('MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected'); } } var constraint = Constraint.create({ label: 'Mouse Constraint', pointA: mouse.position, pointB: { x: 0, y: 0 }, length: 0.01, stiffness: 0.1, angularStiffness: 1, render: { strokeStyle: '#90EE90', lineWidth: 3 } }); var defaults = { type: 'mouseConstraint', mouse: mouse, element: null, body: null, constraint: constraint, collisionFilter: { category: 0x0001, mask: 0xFFFFFFFF, group: 0 } }; var mouseConstraint = Common.extend(defaults, options); Events.on(engine, 'beforeUpdate', function() { var allBodies = Composite.allBodies(engine.world); MouseConstraint.update(mouseConstraint, allBodies); MouseConstraint._triggerEvents(mouseConstraint); }); return mouseConstraint; }; /** * Updates the given mouse constraint. * @private * @method update * @param {MouseConstraint} mouseConstraint * @param {body[]} bodies */ MouseConstraint.update = function(mouseConstraint, bodies) { var mouse = mouseConstraint.mouse, constraint = mouseConstraint.constraint, body = mouseConstraint.body; if (mouse.button === 0) { if (!constraint.bodyB) { for (var i = 0; i < bodies.length; i++) { body = bodies[i]; if (Bounds.contains(body.bounds, mouse.position) && Detector.canCollide(body.collisionFilter, mouseConstraint.collisionFilter)) { for (var j = body.parts.length > 1 ? 1 : 0; j < body.parts.length; j++) { var part = body.parts[j]; if (Vertices.contains(part.vertices, mouse.position)) { constraint.pointA = mouse.position; constraint.bodyB = mouseConstraint.body = body; constraint.pointB = { x: mouse.position.x - body.position.x, y: mouse.position.y - body.position.y }; constraint.angleB = body.angle; Sleeping.set(body, false); Events.trigger(mouseConstraint, 'startdrag', { mouse: mouse, body: body }); break; } } } } } else { Sleeping.set(constraint.bodyB, false); constraint.pointA = mouse.position; } } else { constraint.bodyB = mouseConstraint.body = null; constraint.pointB = null; if (body) Events.trigger(mouseConstraint, 'enddrag', { mouse: mouse, body: body }); } }; /** * Triggers mouse constraint events. * @method _triggerEvents * @private * @param {mouse} mouseConstraint */ MouseConstraint._triggerEvents = function(mouseConstraint) { var mouse = mouseConstraint.mouse, mouseEvents = mouse.sourceEvents; if (mouseEvents.mousemove) Events.trigger(mouseConstraint, 'mousemove', { mouse: mouse }); if (mouseEvents.mousedown) Events.trigger(mouseConstraint, 'mousedown', { mouse: mouse }); if (mouseEvents.mouseup) Events.trigger(mouseConstraint, 'mouseup', { mouse: mouse }); // reset the mouse state ready for the next step Mouse.clearSourceEvents(mouse); }; /* * * Events Documentation * */ /** * Fired when the mouse has moved (or a touch moves) during the last step * * @event mousemove * @param {} event An event object * @param {mouse} event.mouse The engine's mouse instance * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired when the mouse is down (or a touch has started) during the last step * * @event mousedown * @param {} event An event object * @param {mouse} event.mouse The engine's mouse instance * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired when the mouse is up (or a touch has ended) during the last step * * @event mouseup * @param {} event An event object * @param {mouse} event.mouse The engine's mouse instance * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired when the user starts dragging a body * * @event startdrag * @param {} event An event object * @param {mouse} event.mouse The engine's mouse instance * @param {body} event.body The body being dragged * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /** * Fired when the user ends dragging a body * * @event enddrag * @param {} event An event object * @param {mouse} event.mouse The engine's mouse instance * @param {body} event.body The body that has stopped being dragged * @param {} event.source The source object of the event * @param {} event.name The name of the event */ /* * * Properties Documentation * */ /** * A `String` denoting the type of object. * * @property type * @type string * @default "constraint" * @readOnly */ /** * The `Mouse` instance in use. If not supplied in `MouseConstraint.create`, one will be created. * * @property mouse * @type mouse * @default mouse */ /** * The `Body` that is currently being moved by the user, or `null` if no body. * * @property body * @type body * @default null */ /** * The `Constraint` object that is used to move the body during interaction. * * @property constraint * @type constraint */ /** * An `Object` that specifies the collision filter properties. * The collision filter allows the user to define which types of body this mouse constraint can interact with. * See `body.collisionFilter` for more information. * * @property collisionFilter * @type object */ })();