Bug 833511 - Add rotation gesture support for standalone image documents. r=jaws

This commit is contained in:
Brandon Waterloo 2013-01-30 16:31:25 -05:00
parent eb56f4d7b1
commit 848b60d655
5 changed files with 143 additions and 4 deletions

View File

@ -521,9 +521,10 @@ pref("browser.gesture.pinch.out.shift", "");
pref("browser.gesture.pinch.in.shift", "");
#endif
pref("browser.gesture.twist.latched", false);
pref("browser.gesture.twist.threshold", 25);
pref("browser.gesture.twist.right", "");
pref("browser.gesture.twist.left", "");
pref("browser.gesture.twist.threshold", 0);
pref("browser.gesture.twist.right", "cmd_gestureRotateRight");
pref("browser.gesture.twist.left", "cmd_gestureRotateLeft");
pref("browser.gesture.twist.end", "cmd_gestureRotateEnd");
pref("browser.gesture.tap", "cmd_fullZoomReset");
// 0: Nothing happens

View File

@ -84,6 +84,9 @@
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
<command id="cmd_fullZoomToggle" oncommand="ZoomManager.toggleZoom();"/>
<command id="cmd_gestureRotateLeft" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
<command id="cmd_gestureRotateRight" oncommand="gGestureSupport.rotate(event.sourceEvent)"/>
<command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>

View File

@ -738,6 +738,10 @@ const gFormSubmitObserver = {
// the capturing phase and call stopPropagation on every event.
let gGestureSupport = {
_currentRotation: 0,
_lastRotateDelta: 0,
_rotateMomentumThreshold: .75,
/**
* Add or remove mouse gesture event listeners
*
@ -798,6 +802,10 @@ let gGestureSupport = {
aEvent.preventDefault();
this._doAction(aEvent, ["tap"]);
break;
case "MozRotateGesture":
aEvent.preventDefault();
this._doAction(aEvent, ["twist", "end"]);
break;
/* case "MozPressTapGesture":
break; */
}
@ -914,7 +922,7 @@ let gGestureSupport = {
let cmdEvent = document.createEvent("xulcommandevent");
cmdEvent.initCommandEvent("command", true, true, window, 0,
aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey,
aEvent.metaKey, null);
aEvent.metaKey, aEvent);
node.dispatchEvent(cmdEvent);
}
} else {
@ -974,6 +982,123 @@ let gGestureSupport = {
return aDef;
}
},
/**
* Perform rotation for ImageDocuments
*
* @param aEvent
* The MozRotateGestureUpdate event triggering this call
*/
rotate: function(aEvent) {
if (!(content.document instanceof ImageDocument))
return;
let contentElement = content.document.body.firstElementChild;
if (!contentElement)
return;
this.rotation = Math.round(this.rotation + aEvent.delta);
contentElement.style.transform = "rotate(" + this.rotation + "deg)";
this._lastRotateDelta = aEvent.delta;
},
/**
* Perform a rotation end for ImageDocuments
*/
rotateEnd: function() {
if (!(content.document instanceof ImageDocument))
return;
let contentElement = content.document.body.firstElementChild;
if (!contentElement)
return;
let transitionRotation = 0;
// The reason that 360 is allowed here is because when rotating between
// 315 and 360, setting rotate(0deg) will cause it to rotate the wrong
// direction around--spinning wildly.
if (this.rotation <= 45)
transitionRotation = 0;
else if (this.rotation > 45 && this.rotation <= 135)
transitionRotation = 90;
else if (this.rotation > 135 && this.rotation <= 225)
transitionRotation = 180;
else if (this.rotation > 225 && this.rotation <= 315)
transitionRotation = 270;
else
transitionRotation = 360;
// If we're going fast enough, and we didn't already snap ahead of rotation,
// then snap ahead of rotation to simulate momentum
if (this._lastRotateDelta > this._rotateMomentumThreshold &&
this.rotation > transitionRotation)
transitionRotation += 90;
else if (this._lastRotateDelta < -1 * this._rotateMomentumThreshold &&
this.rotation < transitionRotation)
transitionRotation -= 90;
contentElement.classList.add("completeRotation");
contentElement.addEventListener("transitionend", this._clearCompleteRotation);
contentElement.style.transform = "rotate(" + transitionRotation + "deg)";
this.rotation = transitionRotation;
},
/**
* Gets the current rotation for the ImageDocument
*/
get rotation() {
return this._currentRotation;
},
/**
* Sets the current rotation for the ImageDocument
*
* @param aVal
* The new value to take. Can be any value, but it will be bounded to
* 0 inclusive to 360 exclusive.
*/
set rotation(aVal) {
this._currentRotation = aVal % 360;
if (this._currentRotation < 0)
this._currentRotation += 360;
return this._currentRotation;
},
/**
* When the location/tab changes, need to reload the current rotation for the
* image
*/
restoreRotationState: function() {
if (!(content.document instanceof ImageDocument))
return;
let contentElement = content.document.body.firstElementChild;
let transformValue = content.window.getComputedStyle(contentElement, null)
.transform;
if (transformValue == "none") {
this.rotation = 0;
return;
}
// transformValue is a rotation matrix--split it and do mathemagic to
// obtain the real rotation value
transformValue = transformValue.split("(")[1]
.split(")")[0]
.split(",");
this.rotation = Math.round(Math.atan2(transformValue[1], transformValue[0]) *
(180 / Math.PI));
},
/**
* Removes the transition rule by removing the completeRotation class
*/
_clearCompleteRotation: function() {
this.classList.remove("completeRotation");
this.removeEventListener("transitionend", this._clearCompleteRotation);
},
};
var gBrowserInit = {
@ -4187,6 +4312,8 @@ var XULBrowserWindow = {
}
UpdateBackForwardCommands(gBrowser.webNavigation);
gGestureSupport.restoreRotationState();
// See bug 358202, when tabs are switched during a drag operation,
// timers don't fire on windows (bug 203573)
if (aRequest)

View File

@ -14,4 +14,8 @@
background: hsl(0,0%,90%) url("chrome://global/skin/media/imagedoc-lightnoise.png");
color: #222;
}
.completeRotation {
transition: transform 0.3s ease 0s;
}
}

View File

@ -14,4 +14,8 @@
background: hsl(0,0%,90%) url("chrome://global/skin/media/imagedoc-lightnoise.png");
color: #222;
}
.completeRotation {
transition: transform 0.3s ease 0s;
}
}