Bug 835984 - Push start-ui tiles away in 3d space when pressing them. r=jwilde

--HG--
extra : rebase_source : 0a3a60f9b4fb628b1aea8a24e4a33cc584316854
This commit is contained in:
Sam Foster 2013-07-09 18:04:08 -07:00
Родитель e2c5c07610
Коммит f1b0d865de
3 изменённых файлов: 106 добавлений и 26 удалений

Просмотреть файл

@ -640,8 +640,78 @@
]]>
</body>
</method>
<method name="bendItem">
<parameter name="aItem"/>
<parameter name="aEvent"/>
<body><![CDATA[
// apply the transform to the contentBox element of the item
let bendNode = 'richgriditem' == aItem.nodeName && aItem._contentBox;
if (!bendNode)
return;
let event = aEvent;
let rect = bendNode.getBoundingClientRect();
let angle;
let x = (event.clientX - rect.left) / rect.width;
let y = (event.clientY - rect.top) / rect.height;
let perspective = '450px';
// scaling factors for the angle of deflection,
// based on the aspect-ratio of the tile
let aspectRatio = rect.width/rect.height;
let deflectX = 10 * Math.ceil(1/aspectRatio);
let deflectY = 10 * Math.ceil(aspectRatio);
if (Math.abs(x - .5) < .1 && Math.abs(y - .5) < .1) {
bendNode.style.transform = "perspective("+perspective+") translateZ(-10px)";
}
else if (x > y) {
if (1 - y > x) {
angle = Math.ceil((.5 - y) * deflectY);
bendNode.style.transform = "perspective("+perspective+") rotateX(" + angle + "deg)";
bendNode.style.transformOrigin = "center bottom";
} else {
angle = Math.ceil((x - .5) * deflectX);
bendNode.style.transform = "perspective("+perspective+") rotateY(" + angle + "deg)";
bendNode.style.transformOrigin = "left center";
}
} else {
if (1 - y < x) {
angle = -Math.ceil((y - .5) * deflectY);
bendNode.style.transform = "perspective("+perspective+") rotateX(" + angle + "deg)";
bendNode.style.transformOrigin = "center top";
} else {
angle = -Math.ceil((.5 - x) * deflectX);
bendNode.style.transform = "perspective("+perspective+") rotateY(" + angle + "deg)";
bendNode.style.transformOrigin = "right center";
}
}
// mark when bend effect is applied
aItem.setAttribute("bending", true);
]]></body>
</method>
<method name="unbendItem">
<parameter name="aItem"/>
<body><![CDATA[
// clear the 'bend' transform on the contentBox element of the item
let bendNode = 'richgriditem' == aItem.nodeName && aItem._contentBox;
if (bendNode && aItem.hasAttribute("bending")) {
bendNode.style.removeProperty('transform');
bendNode.style.removeProperty('transformOrigin');
aItem.removeAttribute("bending");
}
]]></body>
</method>
</implementation>
<handlers>
<!-- item bend effect handlers -->
<handler event="mousedown" button="0" phase="capturing" action="this.bendItem(event.target, event)"/>
<handler event="touchstart" action="this.bendItem(event.target, event.touches[0])"/>
<handler event="mouseup" button="0" action="this.unbendItem(event.target)"/>
<handler event="mouseout" button="0" action="this.unbendItem(event.target)"/>
<handler event="touchend" action="this.unbendItem(event.target)"/>
<!-- /item bend effect handler -->
<handler event="context-action">
<![CDATA[
// context-action is an event fired by the appbar typically
@ -667,12 +737,16 @@
let transformValue;
switch(state) {
case "cancelled":
// hopefully nothing else is transform-ing the tile
this.unbendItem(event.target);
event.target.removeAttribute('crosssliding');
// hopefully nothing else is transform-ing the tile
event.target.style.removeProperty('transform');
break;
case "dragging":
case "selecting":
// remove bend/depress effect when a cross-slide begins
this.unbendItem(event.target);
event.target.setAttribute("crosssliding", true);
// just track the mouse in the initial phases of the drag gesture
transformValue = (event.direction=='x') ?
@ -727,7 +801,6 @@
this.refresh();
]]>
</constructor>
<property name="_boundNode" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'anon-tile').parentNode;"/>
<property name="_contentBox" onget="return document.getAnonymousElementByAttribute(this, 'class', 'tile-content');"/>
<property name="_textbox" onget="return document.getAnonymousElementByAttribute(this, 'class', 'tile-desc');"/>
<property name="_top" onget="return document.getAnonymousElementByAttribute(this, 'class', 'tile-start-container');"/>
@ -851,6 +924,7 @@
event.stopPropagation();
]]>
</handler>
<handler event="contextmenu">
<![CDATA[
// fires for right-click, long-click and (keyboard) contextmenu input

Просмотреть файл

@ -176,8 +176,6 @@ CrossSlideHandler.prototype = {
return;
}
aEvent.stopPropagation();
if (aEvent.touches.length!==1) {
// cancel if another touch point gets involved
return this.cancel(aEvent);
@ -193,34 +191,38 @@ CrossSlideHandler.prototype = {
let crossAxisDistance = Math.abs(endPt[crossAxis] - startPt[crossAxis]);
// distance along the scrolling axis
let scrollAxisDistance = Math.abs(endPt[scrollAxis] - startPt[scrollAxis]);
let currState = this.drag.state;
let newState = this.getCrossSlideState(crossAxisDistance, scrollAxisDistance);
if (-1 == newState) {
// out of bounds, cancel the event always
return this.cancel(aEvent);
switch (newState) {
case -1 :
// dodgy input/out of bounds
return this.cancel(aEvent);
case CrossSlidingState.STARTED :
break;
case CrossSlidingState.DRAGGING :
if (scrollAxisDistance > this.thresholds.SELECTIONSTART) {
// looks like a pan/scroll was intended
return this.cancel(aEvent);
}
// else fall-thru'
case CrossSlidingState.SELECTING :
case CrossSlidingState.SELECT_SPEED_BUMPING :
case CrossSlidingState.SPEED_BUMPING :
// we're committed to a cross-slide gesture,
// so going out of bounds at this point means aborting
if (!withinCone(crossAxisDistance, scrollAxisDistance)) {
return this.cancel(aEvent);
}
// we're mid-gesture, consume this event
aEvent.stopPropagation();
break;
}
let isWithinCone = withinCone(crossAxisDistance, scrollAxisDistance);
if (currState < CrossSlidingState.SELECTING && !isWithinCone) {
// ignore, no progress to report
return;
if (currState !== newState) {
this.drag.state = newState;
this._fireProgressEvent( CrossSlidingStateNames[newState], aEvent );
}
if (currState >= CrossSlidingState.SELECTING && !isWithinCone) {
// we're committed to a cross-slide gesture,
// so going out of bounds at this point means aborting
return this.cancel(aEvent);
}
if (currState > newState) {
// moved backwards, ignoring
return;
}
this.drag.state = newState;
this._fireProgressEvent( CrossSlidingStateNames[newState], aEvent );
},
_onTouchEnd: function(aEvent){
if (!this.drag)

Просмотреть файл

@ -231,6 +231,10 @@ richgriditem[customColor] {
color: #f1f1f1;
}
richgriditem[bending] > .tile-content {
transform-origin: center center;
}
/* Snapped-view variation
We use the compact, single-column grid treatment for <=320px */