/**
* 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 = parseInt(mouse.element.getAttribute('data-pixel-ratio'), 10) || 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.sourceEvents.mousewheel = event;
};
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, { passive: true });
element.addEventListener('mousedown', mouse.mousedown, { passive: true });
element.addEventListener('mouseup', mouse.mouseup, { passive: true });
element.addEventListener('wheel', mouse.mousewheel, { passive: false });
element.addEventListener('touchmove', mouse.mousemove, { passive: false });
element.addEventListener('touchstart', mouse.mousedown, { passive: false });
element.addEventListener('touchend', mouse.mouseup, { passive: false });
};
/**
* 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)
};
};
})();