• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
12WebInspector.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 */
25WebInspector.TransformController.Events = {
26    TransformChanged: "TransformChanged"
27}
28
29WebInspector.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