1 /* 2 * Copyright 2014 The Chromium Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 /** 8 * @constructor 9 * @extends {WebInspector.Object} 10 * @param {!Element} element 11 */ 12 WebInspector.TransformController = function(element) 13 { 14 this.element = element; 15 element.addEventListener("mousemove", this._onMouseMove.bind(this), false); 16 element.addEventListener("mousedown", this._onMouseDown.bind(this), false); 17 element.addEventListener("mouseup", this._onMouseUp.bind(this), false); 18 element.addEventListener("mousewheel", this._onMouseWheel.bind(this), false); 19 this._reset(); 20 } 21 22 /** 23 * @enum {string} 24 */ 25 WebInspector.TransformController.Events = { 26 TransformChanged: "TransformChanged" 27 } 28 29 WebInspector.TransformController.prototype = { 30 /** 31 * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, function(?Event=))} registerShortcutDelegate 32 */ 33 registerShortcuts: function(registerShortcutDelegate) 34 { 35 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ResetView, this._resetAndNotify.bind(this)); 36 var zoomFactor = 1.1; 37 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, this._onKeyboardZoom.bind(this, zoomFactor)); 38 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, this._onKeyboardZoom.bind(this, 1 / zoomFactor)); 39 var panDistanceInPixels = 6; 40 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanUp, this._onPan.bind(this, 0, -panDistanceInPixels)); 41 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanDown, this._onPan.bind(this, 0, panDistanceInPixels)); 42 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanLeft, this._onPan.bind(this, -panDistanceInPixels, 0)); 43 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.PanRight, this._onPan.bind(this, panDistanceInPixels, 0)); 44 var rotateDegrees = 5; 45 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCWX, this._onKeyboardRotate.bind(this, rotateDegrees, 0)); 46 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCCWX, this._onKeyboardRotate.bind(this, -rotateDegrees, 0)); 47 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCWY, this._onKeyboardRotate.bind(this, 0, -rotateDegrees)); 48 registerShortcutDelegate(WebInspector.ShortcutsScreen.LayersPanelShortcuts.RotateCCWY, this._onKeyboardRotate.bind(this, 0, rotateDegrees)); 49 }, 50 51 _postChangeEvent: function() 52 { 53 this.dispatchEventToListeners(WebInspector.TransformController.Events.TransformChanged); 54 }, 55 56 _reset: function() 57 { 58 this._scale = 1; 59 this._offsetX = 0; 60 this._offsetY = 0; 61 this._rotateX = 0; 62 this._rotateY = 0; 63 }, 64 65 /** 66 * @param {?Event=} event 67 */ 68 _resetAndNotify: function(event) 69 { 70 this._reset(); 71 this._postChangeEvent(); 72 if (event) 73 event.preventDefault(); 74 }, 75 76 /** 77 * @return {number} 78 */ 79 scale: function() 80 { 81 return this._scale; 82 }, 83 84 /** 85 * @return {number} 86 */ 87 offsetX: function() 88 { 89 return this._offsetX; 90 }, 91 92 /** 93 * @return {number} 94 */ 95 offsetY: function() 96 { 97 return this._offsetY; 98 }, 99 100 /** 101 * @return {number} 102 */ 103 rotateX: function() 104 { 105 return this._rotateX; 106 }, 107 108 /** 109 * @return {number} 110 */ 111 rotateY: function() 112 { 113 return this._rotateY; 114 }, 115 116 /** 117 * @param {number} scaleFactor 118 * @param {number} x 119 * @param {number} y 120 */ 121 _onScale: function(scaleFactor, x, y) 122 { 123 this._scale *= scaleFactor; 124 this._offsetX -= (x - this._offsetX) * (scaleFactor - 1); 125 this._offsetY -= (y - this._offsetY) * (scaleFactor - 1); 126 this._postChangeEvent(); 127 }, 128 129 /** 130 * @param {number} offsetX 131 * @param {number} offsetY 132 */ 133 _onPan: function(offsetX, offsetY) 134 { 135 this._offsetX += offsetX; 136 this._offsetY += offsetY; 137 this._postChangeEvent(); 138 }, 139 140 /** 141 * @param {number} rotateX 142 * @param {number} rotateY 143 */ 144 _onRotate: function(rotateX, rotateY) 145 { 146 this._rotateX = rotateX; 147 this._rotateY = rotateY; 148 this._postChangeEvent(); 149 }, 150 151 /** 152 * @param {number} zoomFactor 153 */ 154 _onKeyboardZoom: function(zoomFactor) 155 { 156 this._onScale(zoomFactor, this.element.clientWidth / 2, this.element.clientHeight / 2); 157 }, 158 159 /** 160 * @param {number} rotateX 161 * @param {number} rotateY 162 */ 163 _onKeyboardRotate: function(rotateX, rotateY) 164 { 165 this._onRotate(this._rotateX + rotateX, this._rotateY + rotateY); 166 }, 167 168 /** 169 * @param {?Event} event 170 */ 171 _onMouseWheel: function(event) 172 { 173 if (!event.altKey) { 174 /** @const */ 175 var zoomFactor = 1.1; 176 /** @const */ 177 var mouseWheelZoomSpeed = 1 / 120; 178 var scaleFactor = Math.pow(zoomFactor, event.wheelDeltaY * mouseWheelZoomSpeed); 179 this._onScale(scaleFactor, event.clientX - this.element.totalOffsetLeft(), event.clientY - this.element.totalOffsetTop()); 180 } else { 181 /** @const */ 182 var moveFactor = 1 / 20; 183 this._onPan(event.wheelDeltaX * moveFactor, event.wheelDeltaY * moveFactor); 184 } 185 }, 186 187 /** 188 * @param {?Event} event 189 */ 190 _onMouseMove: function(event) 191 { 192 if (event.which !== 1 || typeof this._originX !== "number") 193 return; 194 this._onRotate(this._oldRotateX + (this._originY - event.clientY) / this.element.clientHeight * 180, this._oldRotateY - (this._originX - event.clientX) / this.element.clientWidth * 180); 195 }, 196 197 /** 198 * @param {?Event} event 199 */ 200 _setReferencePoint: function(event) 201 { 202 this._originX = event.clientX; 203 this._originY = event.clientY; 204 this._oldRotateX = this._rotateX; 205 this._oldRotateY = this._rotateY; 206 }, 207 208 _resetReferencePoint: function() 209 { 210 delete this._originX; 211 delete this._originY; 212 delete this._oldRotateX; 213 delete this._oldRotateY; 214 }, 215 216 /** 217 * @param {?Event} event 218 */ 219 _onMouseDown: function(event) 220 { 221 if (event.which !== 1) 222 return; 223 this._setReferencePoint(event); 224 }, 225 226 /** 227 * @param {?Event} event 228 */ 229 _onMouseUp: function(event) 230 { 231 if (event.which !== 1) 232 return; 233 this._resetReferencePoint(); 234 }, 235 236 __proto__: WebInspector.Object.prototype 237 } 238