var Angle = require('../math/angle/Between'); var Class = require('../utils/Class'); var Distance = require('../math/distance/DistanceBetween'); var FuzzyEqual = require('../math/fuzzy/Equal'); var SmoothStepInterpolation = require('../math/interpolation/SmoothStepInterpolation'); var Vector2 = require('../math/Vector2'); var Pointer = new Class({ initialize: function Pointer(manager, id){ this.manager = manager; this.id = id; this.event; this.downElement; this.upElement; this.camera = null ; this.buttons = 0; this.position = new Vector2(); this.prevPosition = new Vector2(); this.midPoint = new Vector2(-1, -1); this.velocity = new Vector2(); this.angle = 0; this.distance = 0; this.smoothFactor = 0; this.motionFactor = 0.2; this.worldX = 0; this.worldY = 0; this.moveTime = 0; this.downX = 0; this.downY = 0; this.downTime = 0; this.upX = 0; this.upY = 0; this.upTime = 0; this.primaryDown = false ; this.isDown = false ; this.dirty = false ; this.justDown = false ; this.justUp = false ; this.justMoved = false ; this.wasTouch = false ; this.wasCanceled = false ; this.movementX = 0; this.movementY = 0; this.identifier = 0; this.pointerId = null ; this.active = (id === 0)? true : false ; this.time = 0; } , positionToCamera: function (camera, output){ return camera.getWorldPoint(this.x, this.y, output); } , reset: function (time){ this.dirty = false ; this.justDown = false ; this.justUp = false ; this.justMoved = false ; this.time = time; this.movementX = 0; this.movementY = 0; } , updateMotion: function (){ var cx = this.position.x; var cy = this.position.y; var mx = this.midPoint.x; var my = this.midPoint.y; if (cx === mx && cy === my) { return ; } var vx = SmoothStepInterpolation(this.motionFactor, mx, cx); var vy = SmoothStepInterpolation(this.motionFactor, my, cy); if (FuzzyEqual(vx, cx, 0.1)) { vx = cx; } if (FuzzyEqual(vy, cy, 0.1)) { vy = cy; } this.midPoint.set(vx, vy); var dx = cx - vx; var dy = cy - vy; this.velocity.set(dx, dy); this.angle = Angle(vx, vy, cx, cy); this.distance = Math.sqrt(dx * dx + dy * dy); } , up: function (event, time){ if (event.buttons) { this.buttons = event.buttons; } this.event = event; this.upElement = _AN_Read_target('target', event); this.manager.transformPointer(this, event.pageX, event.pageY, false ); if (event.button === 0) { this.primaryDown = false ; this.upX = this.x; this.upY = this.y; this.upTime = time; } this.justUp = true ; this.isDown = false ; this.dirty = true ; this.wasTouch = false ; } , down: function (event, time){ if (event.buttons) { this.buttons = event.buttons; } this.event = event; this.downElement = _AN_Read_target('target', event); this.manager.transformPointer(this, event.pageX, event.pageY, false ); if (event.button === 0) { this.primaryDown = true ; this.downX = this.x; this.downY = this.y; this.downTime = time; } this.justDown = true ; this.isDown = true ; this.dirty = true ; this.wasTouch = false ; } , move: function (event, time){ if (event.buttons) { this.buttons = event.buttons; } this.event = event; this.manager.transformPointer(this, event.pageX, event.pageY, true ); if (this.manager.mouse.locked) { this.movementX += event.movementX || event.mozMovementX || event.webkitMovementX || 0; this.movementY += event.movementY || event.mozMovementY || event.webkitMovementY || 0; } this.justMoved = true ; this.moveTime = time; this.dirty = true ; this.wasTouch = false ; } , touchstart: function (event, time){ if (event.pointerId) { this.pointerId = event.pointerId; } this.identifier = event.identifier; _AN_Write_target('target', this, false , _AN_Read_target('target', event)); this.active = true ; this.buttons = 1; this.event = event; this.downElement = _AN_Read_target('target', event); this.manager.transformPointer(this, event.pageX, event.pageY, false ); this.primaryDown = true ; this.downX = this.x; this.downY = this.y; this.downTime = time; this.justDown = true ; this.isDown = true ; this.dirty = true ; this.wasTouch = true ; this.wasCanceled = false ; } , touchmove: function (event, time){ this.event = event; this.manager.transformPointer(this, event.pageX, event.pageY, true ); this.justMoved = true ; this.moveTime = time; this.dirty = true ; this.wasTouch = true ; } , touchend: function (event, time){ this.buttons = 0; this.event = event; this.upElement = _AN_Read_target('target', event); this.manager.transformPointer(this, event.pageX, event.pageY, false ); this.primaryDown = false ; this.upX = this.x; this.upY = this.y; this.upTime = time; this.justUp = true ; this.isDown = false ; this.dirty = true ; this.wasTouch = true ; this.wasCanceled = false ; this.active = false ; } , touchcancel: function (event){ this.buttons = 0; this.event = event; this.primaryDown = false ; this.justUp = false ; this.isDown = false ; this.dirty = true ; this.wasTouch = true ; this.wasCanceled = true ; this.active = false ; } , noButtonDown: function (){ return (this.buttons === 0); } , leftButtonDown: function (){ return (this.buttons & 1); } , rightButtonDown: function (){ return (this.buttons & 2); } , middleButtonDown: function (){ return (this.buttons & 4); } , backButtonDown: function (){ return (this.buttons & 8); } , forwardButtonDown: function (){ return (this.buttons & 16); } , getDistance: function (){ if (this.isDown) { return Distance(this.downX, this.downY, this.x, this.y); } else { return Distance(this.downX, this.downY, this.upX, this.upY); } } , getDistanceX: function (){ if (this.isDown) { return Math.abs(this.downX - this.x); } else { return Math.abs(this.downX - this.upX); } } , getDistanceY: function (){ if (this.isDown) { return Math.abs(this.downY - this.y); } else { return Math.abs(this.downY - this.upY); } } , getDuration: function (){ if (this.isDown) { return (this.time - this.downTime); } else { return (this.upTime - this.downTime); } } , getAngle: function (){ if (this.isDown) { return Angle(this.downX, this.downY, this.x, this.y); } else { return Angle(this.downX, this.downY, this.upX, this.upY); } } , getInterpolatedPosition: function (steps, out){ if (steps === undefined) { steps = 10; } if (out === undefined) { out = [] ; } var prevX = this.prevPosition.x; var prevY = this.prevPosition.y; var curX = this.position.x; var curY = this.position.y; for (var i = 0; i < steps; i++ ){ var t = (1 / steps) * i; out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY)} ; } return out; } , destroy: function (){ this.camera = null ; this.manager = null ; this.position = null ; } , x: { get: function (){ return this.position.x; } , set: function (value){ this.position.x = value; } } , y: { get: function (){ return this.position.y; } , set: function (value){ this.position.y = value; } } } ); module.exports = Pointer;