From 24b483db367291b72170f969de78efcb1a9b95bd Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Thu, 3 May 2012 22:53:07 -0700 Subject: integrating the latest montage version Signed-off-by: Valerio Virgillito --- .../montage/ui/composer/translate-composer.js | 641 +++++++++++---------- 1 file changed, 347 insertions(+), 294 deletions(-) (limited to 'node_modules/montage/ui/composer/translate-composer.js') diff --git a/node_modules/montage/ui/composer/translate-composer.js b/node_modules/montage/ui/composer/translate-composer.js index 6e762af9..86e6fb09 100644 --- a/node_modules/montage/ui/composer/translate-composer.js +++ b/node_modules/montage/ui/composer/translate-composer.js @@ -3,19 +3,24 @@ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. */ + /*global require,exports */ /** @module montage/ui/composer/translate-composer - @requires montage + @requires montage/core/core @requires montage/ui/composer/composer */ var Montage = require("montage").Montage, Composer = require("ui/composer/composer").Composer, defaultEventManager = require("core/event/event-manager").defaultEventManager; /** + Provides translateX and translateY properties that are updated when the + user clicks/touches and drags on the given element. Should be used wherever + a user interacts with an element by dragging it. + @class module:montage/ui/composer/translate-composer.TranslateComposer @extends module:montage/ui/composer/composer.Composer */ -var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** @lends module:montage/ui/event/composer/translate-composer.TranslateComposer# */ { +var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** @lends module:montage/ui/composer/translate-composer.TranslateComposer# */ { /** These elements perform some native action when clicked/touched and so we @@ -53,11 +58,16 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** value: 1 }, + /** + How many pixels to translate by for each pixel of cursor movement. + @type {Number} + @default 1 + */ pointerSpeedMultiplier: { - get: function () { + get: function() { return this._pointerSpeedMultiplier; }, - set: function (value) { + set: function(value) { this._pointerSpeedMultiplier = value; } }, @@ -76,33 +86,59 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** value: false }, + _allowFloats: { + enumerable: false, + value: false + }, + /** + Allow (@link translateX} and {@link translateY} to be floats. + @type {Boolean} + @default false + */ + allowFloats: { + get: function() { + return this._allowFloats; + }, + set: function(value) { + if (this._allowFloats !== value) { + this._allowFloats = value; + this.translateX = this._translateX; + this.translateY = this._translateY; + } + } + }, + _translateX: { enumerable: false, value: 0 }, - + /** + Amount of translation in the X (left/right) direction. Can be inverted with + {@link invertXAxis}, and restricted to a range with + {@link minTranslateX} and {@link maxTranslateX}. + @type {Number} + @default 0 + */ translateX: { - get: function () { + get: function() { return this._translateX; }, - set: function (value) { - if (this._axis==="vertical") { - this._translateX=0; + set: function(value) { + if (this._axis === "vertical") { + this._translateX = this._minTranslateX || 0; } else { - var tmp=isNaN(value)?0:value>>0; + var tmp = isNaN(value) ? 0 : this._allowFloats ? parseFloat(value) : value >> 0; - if ((!this._hasBouncing)||(!this._isSelfUpdate)) { - if (tmp<0) { - tmp=0; - } - if (tmp>this._maxTranslateX) { - tmp=this._maxTranslateX; - } - if (!this._isSelfUpdate) { - this.isAnimating = false; - } + if (this._minTranslateX !== null && tmp < this._minTranslateX) { + tmp = this._minTranslateX; } - this._translateX=tmp; + if (this._maxTranslateX !== null && tmp > this._maxTranslateX) { + tmp = this._maxTranslateX; + } + if (!this._isSelfUpdate) { + this.isAnimating = false; + } + this._translateX = tmp; } } }, @@ -111,77 +147,143 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** enumerable: false, value: 0 }, - + /** + Amount of translation in the Y (up/down) direction. Can be inverted with + {@link invertYAxis}, and restricted to a range with + {@link minTranslateY} and {@link maxTranslateY}. + @type {Number} + @default 0 + */ translateY: { - get: function () { + get: function() { return this._translateY; }, - set: function (value) { - if (this._axis==="horizontal") { - this._translateY=0; + set: function(value) { + if (this._axis === "horizontal") { + this._translateY = this._minTranslateY || 0; } else { - var tmp=isNaN(value)?0:value>>0; + var tmp = isNaN(value) ? 0 : this._allowFloats ? parseFloat(value) : value >> 0; - if ((!this._hasBouncing)||(!this._isSelfUpdate)) { - if (tmp<0) { - tmp=0; - } - if (tmp>this._maxTranslateY) { - tmp=this._maxTranslateY; - } - if (!this._isSelfUpdate) { - this.isAnimating = false; - } + if (this._minTranslateY !== null && tmp < this._minTranslateY) { + tmp = this._minTranslateY; + } + if (this._maxTranslateY !== null && tmp > this._maxTranslateY) { + tmp = this._maxTranslateY; } - this._translateY=tmp; + if (!this._isSelfUpdate) { + this.isAnimating = false; + } + this._translateY = tmp; } } }, - _maxTranslateX: { + _minTranslateX: { enumerable: false, - value: 0 + value: null }, + /** + The minimum value {@link translateX} can take. If set to null then + there is no minimum. + @type {number|null} + @default null + */ + minTranslateX: { + get: function() { + return this._minTranslateX; + }, + set: function(value) { + if (value !== null) { + value = parseFloat(value); + } + if (this._minTranslateX != value) { + if (value !== null && this._translateX < value) { + this.translateX = value; + } + this._minTranslateX = value; + } + } + }, + _maxTranslateX: { + enumerable: false, + value: null + }, + /** + The maximum value {@link translateX} can take. If set to null then + there is no maximum. + @type {number|null} + @default null + */ maxTranslateX: { - get: function () { + get: function() { return this._maxTranslateX; }, - set: function (value) { - var tmp=isNaN(value)?0:value>>0; - - if (tmp<0) { - tmp=0; + set: function(value) { + if (value !== null) { + value = parseFloat(value); } - if (this._maxTranslateX!=tmp) { - if (this._translateX>this._maxTranslateX) { - this.translateX=this._maxTranslateX; + + if (this._maxTranslateX != value) { + if (value !== null && this._translateX > value) { + this.translateX = value; } - this._maxTranslateX=tmp; + this._maxTranslateX = value; } } }, - _maxTranslateY: { + _minTranslateY: { enumerable: false, - value: 0 + value: null }, + /** + The minimum value {@link translateY} can take. If set to null then + there is no minimum. + @type {number|null} + @default null + */ + minTranslateY: { + get: function() { + return this._minTranslateY; + }, + set: function(value) { + if (value !== null) { + value = parseFloat(value); + } + if (this._minTranslateY != value) { + if (value !== null && this._translateY < value) { + this.translateY = value; + } + this._minTranslateY = value; + } + } + }, + _maxTranslateY: { + enumerable: false, + value: null + }, + /** + The maximum value {@link translateY} can take. If set to null then + there is no maximum. + @type {number|null} + @default null + */ maxTranslateY: { - get: function () { + get: function() { return this._maxTranslateY; }, - set: function (value) { - var tmp=isNaN(value)?0:value>>0; - - if (tmp<0) { - tmp=0; + set: function(value) { + if (value !== null) { + value = parseFloat(value); } - if (this._maxTranslateY!=tmp) { - if (this._translateY>this._maxTranslateY) { - this.translateY=this._maxTranslateY; + + if (this._maxTranslateY != value) { + if (value !== null && this._translateY > value) { + this.translateY = value; } - this._maxTranslateY=tmp; + this._maxTranslateY = value; } } }, @@ -190,63 +292,118 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** enumerable: false, value: "both" }, + /** + Which axis translation is restricted to. + Can be "vertical", "horizontal" or "both". + @type {String} + @default "both" + */ axis: { - get: function () { + get: function() { return this._axis; }, - set: function (value) { + set: function(value) { switch (value) { - case "vertical": - case "horizontal": - this._axis=value; - break; - default: - this._axis="both"; - break; + case "vertical": + case "horizontal": + this._axis = value; + this.translateX = this._translateX; + this.translateY = this._translateY; + break; + default: + this._axis = "both"; + break; } } }, - _invertAxis: { + /** + Invert direction of translation on both axes. + + This inverts the effect of cursor motion on both axes. For example + if set to true moving the mouse up will increase the value of + translateY instead of decreasing it. + + Depends on invertXAxis and invertYAxis. + @type {Boolean} + @default false + */ + invertAxis: { + depends: ["invertXAxis", "invertYAxis"], + get: function() { + return (this._invertXAxis === this._invertYAxis) ? this._invertXAxis : null; + }, + set: function(value) { + this.invertXAxis = value; + this.invertYAxis = value; + } + }, + _invertXAxis: { value: false, enumerable: false }, + /** + Invert direction of translation along the X axis. - invertAxis: { + This inverts the effect of left/right cursor motion on translateX. + @type {Boolean} + @default false + */ + invertXAxis: { get: function() { - return this._invertAxis; + return this._invertXAxis; }, set: function(value) { - this._invertAxis=value?true:false; + this._invertXAxis = !!value; } }, - - _hasMomentum: { - enumerable: false, - value: true + _invertYAxis: { + value: false, + enumerable: false }, + /** + Invert direction of translation along the Y axis. - hasMomentum: { - get: function () { - return this._hasMomentum; + This inverts the effect of up/down cursor motion on translateX. + @type {Boolean} + @default false + */ + invertYAxis: { + get: function() { + return this._invertYAxis; }, - set: function (value) { - this._hasMomentum=value?true:false; + set: function(value) { + this._invertYAxis = !!value; } }, - _hasBouncing: { + /** + How fast the cursor has to be moving before translating starts. Only + applied when another component has claimed the pointer. + @type {Number} + @default 500 + */ + startTranslateSpeed: { + value: 500 + }, + + _hasMomentum: { enumerable: false, value: true }, - hasBouncing: { - get: function () { - return this._hasBouncing; + /** + Whether to keep translating after the user has releases the cursor. + @type {Boolean} + @default true + */ + hasMomentum: { + get: function() { + return this._hasMomentum; }, - set: function (value) { - this._hasBouncing=value?true:false; + set: function(value) { + this._hasMomentum = value ? true : false; } }, @@ -256,31 +413,18 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** }, _momentumDuration: { - get: function () { + get: function() { return this.__momentumDuration; }, - set: function (value) { - this.__momentumDuration=isNaN(value)?1:value>>0; - if (this.__momentumDuration<1) this.__momentumDuration=1; + set: function(value) { + this.__momentumDuration = isNaN(value) ? 1 : value >> 0; + if (this.__momentumDuration < 1) { + this.__momentumDuration = 1; + } }, enumerable: false }, - __bouncingDuration: { - enumerable: false, - value: 750 - }, - - _bouncingDuration: { - get: function () { - return this.__bouncingDuration; - }, - set: function (value) { - this.__bouncingDuration=isNaN(value)?1:value>>0; - if (this.__bouncingDuration<1) this.__bouncingDuration=1; - } - }, - _pointerX: { enumerable: false, value: null @@ -303,14 +447,14 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** _start: { enumerable: false, - value: function (x, y, target) { + value: function(x, y, target) { this.pointerStartEventPosition = { pageX: x, pageY: y, target: target }; - this._pointerX=x; - this._pointerY=y; + this._pointerX = x; + this._pointerY = y; if (window.Touch) { document.addEventListener("touchend", this, true); document.addEventListener("touchmove", this, true); @@ -340,14 +484,9 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** } }, -/** - Description TODO - @function - @param {Event} event TODO - */ captureMousedown: { enumerable: false, - value: function (event) { + value: function(event) { if (event.button !== 0) { return; } @@ -369,10 +508,11 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** If nobody else claimed this pointer, we should handle it now @function @param {Event} event TODO + @private */ handleMousedown: { enumerable: false, - value: function (event) { + value: function(event) { if (event.button === 0 && !this.eventManager.componentClaimingPointer(this._observedPointer, this)) { this.eventManager.claimPointer(this._observedPointer, this); this._start(event.clientX, event.clientY, event.target); @@ -383,7 +523,7 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** captureMousemove: { enumerable: false, - value: function (event) { + value: function(event) { if (this.eventManager.isPointerClaimedByComponent(this._observedPointer, this)) { event.preventDefault(); @@ -397,7 +537,7 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** captureMouseup: { enumerable: false, - value: function (event) { + value: function(event) { this._end(event); } }, @@ -422,7 +562,7 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** captureTouchstart: { enumerable: false, - value: function (event) { + value: function(event) { if (this._shouldPreventDefault(event)) { event.preventDefault(); } @@ -457,7 +597,7 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** captureTouchmove: { enumerable: false, - value: function (event) { + value: function(event) { var i = 0, len = event.changedTouches.length; while (i < len && event.changedTouches[i].identifier !== this._observedPointer) { @@ -478,7 +618,7 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** captureTouchend: { enumerable: false, - value: function (event) { + value: function(event) { var i = 0, len = event.changedTouches.length; while (i < len && !this.eventManager.isPointerClaimedByComponent(event.changedTouches[i].identifier, this)) { i++; @@ -532,8 +672,7 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** this._stealPointer(); } - } else if (speed >= 500) { - // TODO not hardcode this threshold speed + } else if (speed >= this.startTranslateSpeed) { this._stealPointer(); } @@ -553,14 +692,15 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** handleMousewheel: { enumerable: false, - value: function (event) { + value: function(event) { var self = this; var oldTranslateY = this._translateY; - this.translateY = this._translateY - (event.wheelDeltaY * 20) / 120; this._dispatchTranslateStart(); + this.translateY = this._translateY - ((event.wheelDeltaY * 20) / 120); + this._dispatchTranslate(); window.clearTimeout(this._translateEndTimeout); - this._translateEndTimeout = window.setTimeout(function () { + this._translateEndTimeout = window.setTimeout(function() { self._dispatchTranslateEnd(); }, 400); @@ -575,32 +715,28 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** _move: { enumerable: false, - value: function (x, y) { + value: function(x, y) { var pointerDelta; - this._isSelfUpdate=true; - if (this._axis!="vertical") { - pointerDelta = this._invertAxis ? (this._pointerX-x) : (x-this._pointerX); - if ((this._translateX<0)||(this._translateX>this._maxTranslateX)) { - this.translateX+=((pointerDelta)/2)*this._pointerSpeedMultiplier; - } else { - this.translateX+=(pointerDelta)*this._pointerSpeedMultiplier; - } - } - if (this._axis!="horizontal") { - pointerDelta = this._invertAxis ? (this._pointerY-y) : (y-this._pointerY); - if ((this._translateY<0)||(this._translateY>this._maxTranslateY)) { - this.translateY+=((pointerDelta)/2)*this._pointerSpeedMultiplier; - } else { - this.translateY+=(pointerDelta)*this._pointerSpeedMultiplier; - } - } - this._isSelfUpdate=false; - this._pointerX=x; - this._pointerY=y; + if (this._isFirstMove) { - this._dispatchTranslateStart(); + this._dispatchTranslateStart(this._translateX, this._translateY); this._isFirstMove = false; } + + this._isSelfUpdate = true; + if (this._axis != "vertical") { + pointerDelta = this._invertXAxis ? (this._pointerX - x) : (x - this._pointerX); + this.translateX += pointerDelta * this._pointerSpeedMultiplier; + } + if (this._axis != "horizontal") { + pointerDelta = this._invertYAxis ? (this._pointerY - y) : (y - this._pointerY); + this.translateY += pointerDelta * this._pointerSpeedMultiplier; + } + this._isSelfUpdate = false; + + this._pointerX = x; + this._pointerY = y; + if (this._shouldDispatchTranslate) { this._dispatchTranslate(); } @@ -614,42 +750,45 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** _bezierTValue: { enumerable: false, - value: function (x, p1x, p1y, p2x, p2y) { - var a=1-3*p2x+3*p1x, - b=3*p2x-6*p1x, - c=3*p1x, - t=.5, - der, - i, k, tmp; + value: function(x, p1x, p1y, p2x, p2y) { + var a = 1 - 3 * p2x + 3 * p1x, + b = 3 * p2x - 6 * p1x, + c = 3 * p1x, + t = 0.5, + der, i, k, tmp; - for (i=0; i<10; i++) { - tmp=t*t; - der=3*a*tmp+2*b*t+c; - k=1-t; - t-=((3*(k*k*t*p1x+k*tmp*p2x)+tmp*t-x)/der); // der==0 + for (i = 0; i < 10; i++) { + tmp = t * t; + der = 3 * a * tmp + 2 * b * t + c; + k = 1 - t; + t -= ((3 * (k * k * t * p1x + k * tmp * p2x) + tmp * t - x) / der); // der==0 } - tmp=t*t; - k=1-t; - return 3*(k*k*t*p1y+k*tmp*p2y)+tmp*t; + tmp = t * t; + k = 1 - t; + return 3 * (k * k * t * p1y + k * tmp * p2y) + tmp * t; } }, _dispatchTranslateStart: { enumerable: false, - value: function () { + value: function(x, y) { var translateStartEvent = document.createEvent("CustomEvent"); translateStartEvent.initCustomEvent("translateStart", true, true, null); + translateStartEvent.translateX = x; + translateStartEvent.translateY = y; this.dispatchEvent(translateStartEvent); } }, _dispatchTranslateEnd: { enumerable: false, - value: function () { + value: function() { var translateEndEvent = document.createEvent("CustomEvent"); translateEndEvent.initCustomEvent("translateEnd", true, true, null); + translateEndEvent.translateX = this._translateX; + translateEndEvent.translateY = this._translateY; this.dispatchEvent(translateEndEvent); } }, @@ -668,156 +807,70 @@ var TranslateComposer = exports.TranslateComposer = Montage.create(Composer,/** _end: { enumerable: false, - value: function (event) { + value: function(event) { - var animateBouncingX=false, - animateBouncingY=false, - animateMomentum=false, + var animateMomentum=false, momentumX, momentumY, - startX=this._translateX, - startY, - posX=startX, - posY, - endX=startX, - endY, + startX = this._translateX, + startY = this._translateY, + posX = startX, + posY = startY, + endX = startX, + endY = startY, self=this, - startTimeBounceX=false, - startTimeBounceY=false, startTime=Date.now(); - startY=this._translateY; - posY=startY; - endY=startY; - if ((this._hasMomentum)&&(event.velocity.speed>40)) { - if (this._axis!="vertical") { - momentumX=event.velocity.x*this._pointerSpeedMultiplier; + if ((this._hasMomentum) && (event.velocity.speed > 40)) { + if (this._axis != "vertical") { + momentumX = event.velocity.x * this._pointerSpeedMultiplier * (this._invertXAxis ? 1 : -1); } else { - momentumX=0; + momentumX = 0; } - if (this._axis!="horizontal") { - momentumY=event.velocity.y*this._pointerSpeedMultiplier; + if (this._axis != "horizontal") { + momentumY = event.velocity.y * this._pointerSpeedMultiplier * (this._invertYAxis ? 1 : -1); } else { - momentumY=0; + momentumY = 0; } - endX=startX-(momentumX*this.__momentumDuration/2000); - endY=startY-(momentumY*this.__momentumDuration/2000); - animateMomentum=true; + endX = startX - (momentumX * this.__momentumDuration / 2000); + endY = startY - (momentumY * this.__momentumDuration / 2000); + animateMomentum = true; } - this._animationInterval=function () { - var time=Date.now(), t, tmpX, tmpY; + this._animationInterval = function() { + var time = Date.now(), + t, tmpX, tmpY; if (animateMomentum) { - t=time-startTime; - if (tself.__bouncingDuration) { - t=self.__bouncingDuration; - } - tmpX=tmpX*(1-self._bezierTValue(t/self.__bouncingDuration, .17, .93, .19, 1)); - } else { - tmpX=0; - animateBouncingX=false; - } - } else { - animateBouncingX=false; - } - } - - if (endY<0) { - if (tmpY<0) { - if (!startTimeBounceY) { - animateBouncingY=true; - startTimeBounceY=time; - } - t=time-startTimeBounceY; - if ((tself.__bouncingDuration) { - t=self.__bouncingDuration; - } - tmpY=tmpY*(1-self._bezierTValue(t/self.__bouncingDuration, .17, .93, .19, 1)); - } else { - tmpY=0; - animateBouncingY=false; - } - } else { - animateBouncingY=false; - } - } - - if (endX>self._maxTranslateX) { - if (tmpX>self._maxTranslateX) { - if (!startTimeBounceX) { - animateBouncingX=true; - startTimeBounceX=time; - } - t=time-startTimeBounceX; - if ((tself.__bouncingDuration) { - t=self.__bouncingDuration; - } - tmpX=self._maxTranslateX+(tmpX-self._maxTranslateX)*(1-self._bezierTValue(t/self.__bouncingDuration, .17, .93, .19, 1)); - } else { - tmpX=self._maxTranslateX; - animateBouncingX=false; - } - } else { - animateBouncingX=false; - } - } + tmpX = posX; + tmpY = posY; - if (endY>self._maxTranslateY) { - if (tmpY>self._maxTranslateY) { - if (!startTimeBounceY) { - animateBouncingY=true; - startTimeBounceY=time; - } - t=time-startTimeBounceY; - if ((tself.__bouncingDuration) { - t=self.__bouncingDuration; - } - tmpY=self._maxTranslateY+(tmpY-self._maxTranslateY)*(1-self._bezierTValue(t/self.__bouncingDuration, .17, .93, .19, 1)); - } else { - tmpY=self._maxTranslateY; - animateBouncingY=false; - } - } else { - animateBouncingY=false; - } - } - } - self._isSelfUpdate=true; - self.translateX=tmpX; - self.translateY=tmpY; - self._isSelfUpdate=false; - self.isAnimating = animateMomentum||animateBouncingX||animateBouncingY; + self._isSelfUpdate = true; + self.translateX = tmpX; + self.translateY = tmpY; + self._isSelfUpdate = false; + self.isAnimating = animateMomentum; if (self.isAnimating) { - self.needsFrame=true; + self.needsFrame = true; } else { this._dispatchTranslateEnd(); } }; - this._animationInterval(); + if (animateMomentum) { + this._animationInterval(); + } else if (!this._isFirstMove) { + // Only dispatch a translateEnd if a translate start has occured + this._dispatchTranslateEnd(); + } this._releaseInterest(); } }, -- cgit v1.2.3