Home | History | Annotate | Download | only in timeline
      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