UNPKG

matter-js

Version:

a 2D rigid body physics engine for the web

202 lines (170 loc) 6.92 kB
/** * The `Matter.Mouse` module contains methods for creating and manipulating mouse inputs. * * @class Mouse */ var Mouse = {}; module.exports = Mouse; var Common = require('../core/Common'); (function() { /** * Creates a mouse input. * @method create * @param {HTMLElement} element * @return {mouse} A new mouse */ Mouse.create = function(element) { var mouse = {}; if (!element) { Common.log('Mouse.create: element was undefined, defaulting to document.body', 'warn'); } mouse.element = element || document.body; mouse.absolute = { x: 0, y: 0 }; mouse.position = { x: 0, y: 0 }; mouse.mousedownPosition = { x: 0, y: 0 }; mouse.mouseupPosition = { x: 0, y: 0 }; mouse.offset = { x: 0, y: 0 }; mouse.scale = { x: 1, y: 1 }; mouse.wheelDelta = 0; mouse.button = -1; mouse.pixelRatio = mouse.element.getAttribute('data-pixel-ratio') || 1; mouse.sourceEvents = { mousemove: null, mousedown: null, mouseup: null, mousewheel: null }; mouse.mousemove = function(event) { var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio), touches = event.changedTouches; if (touches) { mouse.button = 0; event.preventDefault(); } mouse.absolute.x = position.x; mouse.absolute.y = position.y; mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x; mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y; mouse.sourceEvents.mousemove = event; }; mouse.mousedown = function(event) { var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio), touches = event.changedTouches; if (touches) { mouse.button = 0; event.preventDefault(); } else { mouse.button = event.button; } mouse.absolute.x = position.x; mouse.absolute.y = position.y; mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x; mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y; mouse.mousedownPosition.x = mouse.position.x; mouse.mousedownPosition.y = mouse.position.y; mouse.sourceEvents.mousedown = event; }; mouse.mouseup = function(event) { var position = Mouse._getRelativeMousePosition(event, mouse.element, mouse.pixelRatio), touches = event.changedTouches; if (touches) { event.preventDefault(); } mouse.button = -1; mouse.absolute.x = position.x; mouse.absolute.y = position.y; mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x; mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y; mouse.mouseupPosition.x = mouse.position.x; mouse.mouseupPosition.y = mouse.position.y; mouse.sourceEvents.mouseup = event; }; mouse.mousewheel = function(event) { mouse.wheelDelta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail)); event.preventDefault(); }; Mouse.setElement(mouse, mouse.element); return mouse; }; /** * Sets the element the mouse is bound to (and relative to). * @method setElement * @param {mouse} mouse * @param {HTMLElement} element */ Mouse.setElement = function(mouse, element) { mouse.element = element; element.addEventListener('mousemove', mouse.mousemove); element.addEventListener('mousedown', mouse.mousedown); element.addEventListener('mouseup', mouse.mouseup); element.addEventListener('mousewheel', mouse.mousewheel); element.addEventListener('DOMMouseScroll', mouse.mousewheel); element.addEventListener('touchmove', mouse.mousemove); element.addEventListener('touchstart', mouse.mousedown); element.addEventListener('touchend', mouse.mouseup); }; /** * Clears all captured source events. * @method clearSourceEvents * @param {mouse} mouse */ Mouse.clearSourceEvents = function(mouse) { mouse.sourceEvents.mousemove = null; mouse.sourceEvents.mousedown = null; mouse.sourceEvents.mouseup = null; mouse.sourceEvents.mousewheel = null; mouse.wheelDelta = 0; }; /** * Sets the mouse position offset. * @method setOffset * @param {mouse} mouse * @param {vector} offset */ Mouse.setOffset = function(mouse, offset) { mouse.offset.x = offset.x; mouse.offset.y = offset.y; mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x; mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y; }; /** * Sets the mouse position scale. * @method setScale * @param {mouse} mouse * @param {vector} scale */ Mouse.setScale = function(mouse, scale) { mouse.scale.x = scale.x; mouse.scale.y = scale.y; mouse.position.x = mouse.absolute.x * mouse.scale.x + mouse.offset.x; mouse.position.y = mouse.absolute.y * mouse.scale.y + mouse.offset.y; }; /** * Gets the mouse position relative to an element given a screen pixel ratio. * @method _getRelativeMousePosition * @private * @param {} event * @param {} element * @param {number} pixelRatio * @return {} */ Mouse._getRelativeMousePosition = function(event, element, pixelRatio) { var elementBounds = element.getBoundingClientRect(), rootNode = (document.documentElement || document.body.parentNode || document.body), scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : rootNode.scrollLeft, scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : rootNode.scrollTop, touches = event.changedTouches, x, y; if (touches) { x = touches[0].pageX - elementBounds.left - scrollX; y = touches[0].pageY - elementBounds.top - scrollY; } else { x = event.pageX - elementBounds.left - scrollX; y = event.pageY - elementBounds.top - scrollY; } return { x: x / (element.clientWidth / (element.width || element.clientWidth) * pixelRatio), y: y / (element.clientHeight / (element.height || element.clientHeight) * pixelRatio) }; }; })();