| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |  | 
|    2 // Use of this source code is governed by a BSD-style license that can be |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 /** |  | 
|    6  * @constructor |  | 
|    7  * @extends {WebInspector.VBox} |  | 
|    8  */ |  | 
|    9 WebInspector.BezierEditor = function() |  | 
|   10 { |  | 
|   11     WebInspector.VBox.call(this, true); |  | 
|   12     this.registerRequiredCSS("elements/bezierEditor.css"); |  | 
|   13     this.contentElement.tabIndex = 0; |  | 
|   14  |  | 
|   15     // Preview UI |  | 
|   16     this._previewElement = this.contentElement.createChild("div", "bezier-previe
     w-container"); |  | 
|   17     this._previewElement.createChild("div", "bezier-preview-animation"); |  | 
|   18     this._previewElement.addEventListener("click", this._startPreviewAnimation.b
     ind(this)); |  | 
|   19     this._previewOnion = this.contentElement.createChild("div", "bezier-preview-
     onion"); |  | 
|   20     this._previewOnion.addEventListener("click", this._startPreviewAnimation.bin
     d(this)); |  | 
|   21  |  | 
|   22     this._outerContainer = this.contentElement.createChild("div", "bezier-contai
     ner"); |  | 
|   23  |  | 
|   24     // Presets UI |  | 
|   25     this._presetsContainer = this._outerContainer.createChild("div", "bezier-pre
     sets"); |  | 
|   26     this._presetUI = new WebInspector.BezierUI(40, 40, 0, 2, false); |  | 
|   27     this._presetCategories = []; |  | 
|   28     for (var i = 0; i < WebInspector.BezierEditor.Presets.length; i++) { |  | 
|   29         this._presetCategories[i] = this._createCategory(WebInspector.BezierEdit
     or.Presets[i]); |  | 
|   30         this._presetsContainer.appendChild(this._presetCategories[i].icon); |  | 
|   31     } |  | 
|   32  |  | 
|   33     // Curve UI |  | 
|   34     this._curveUI = new WebInspector.BezierUI(150, 250, 50, 7, true); |  | 
|   35     this._curve = this._outerContainer.createSVGChild("svg", "bezier-curve"); |  | 
|   36     WebInspector.installDragHandle(this._curve, this._dragStart.bind(this), this
     ._dragMove.bind(this), this._dragEnd.bind(this), "default"); |  | 
|   37  |  | 
|   38     this._header = this.contentElement.createChild("div", "bezier-header"); |  | 
|   39     var minus = this._createPresetModifyIcon(this._header, "bezier-preset-minus"
     , "M 12 6 L 8 10 L 12 14"); |  | 
|   40     var plus = this._createPresetModifyIcon(this._header, "bezier-preset-plus", 
     "M 8 6 L 12 10 L 8 14"); |  | 
|   41     minus.addEventListener("click", this._presetModifyClicked.bind(this, false))
     ; |  | 
|   42     plus.addEventListener("click", this._presetModifyClicked.bind(this, true)); |  | 
|   43     this._label = this._header.createChild("span", "source-code bezier-display-v
     alue"); |  | 
|   44 } |  | 
|   45  |  | 
|   46 /** @enum {symbol} */ |  | 
|   47 WebInspector.BezierEditor.Events = { |  | 
|   48     BezierChanged: Symbol("BezierChanged") |  | 
|   49 } |  | 
|   50  |  | 
|   51 WebInspector.BezierEditor.Presets = [ |  | 
|   52     [ |  | 
|   53         { name: "ease-in-out", value: "ease-in-out" }, |  | 
|   54         { name: "In Out · Sine", value: "cubic-bezier(0.45, 0.05, 0.55, 0.95)" }
     , |  | 
|   55         { name: "In Out · Quadratic", value: "cubic-bezier(0.46, 0.03, 0.52, 0.9
     6)" }, |  | 
|   56         { name: "In Out · Cubic", value: "cubic-bezier(0.65, 0.05, 0.36, 1)" }, |  | 
|   57         { name: "Fast Out, Slow In", value: "cubic-bezier(0.4, 0, 0.2, 1)" }, |  | 
|   58         { name: "In Out · Back", value: "cubic-bezier(0.68, -0.55, 0.27, 1.55)" 
     } |  | 
|   59     ], |  | 
|   60     [ |  | 
|   61         { name: "Fast Out, Linear In", value: "cubic-bezier(0.4, 0, 1, 1)" }, |  | 
|   62         { name: "ease-in", value: "ease-in" }, |  | 
|   63         { name: "In · Sine", value: "cubic-bezier(0.47, 0, 0.75, 0.72)" }, |  | 
|   64         { name: "In · Quadratic", value: "cubic-bezier(0.55, 0.09, 0.68, 0.53)" 
     }, |  | 
|   65         { name: "In · Cubic", value: "cubic-bezier(0.55, 0.06, 0.68, 0.19)" }, |  | 
|   66         { name: "In · Back", value: "cubic-bezier(0.6, -0.28, 0.74, 0.05)" } |  | 
|   67     ], |  | 
|   68     [ |  | 
|   69         { name: "ease-out", value: "ease-out" }, |  | 
|   70         { name: "Out · Sine", value: "cubic-bezier(0.39, 0.58, 0.57, 1)" }, |  | 
|   71         { name: "Out · Quadratic", value: "cubic-bezier(0.25, 0.46, 0.45, 0.94)"
      }, |  | 
|   72         { name: "Out · Cubic", value: "cubic-bezier(0.22, 0.61, 0.36, 1)" }, |  | 
|   73         { name: "Linear Out, Slow In", value: "cubic-bezier(0, 0, 0.2, 1)" }, |  | 
|   74         { name: "Out · Back", value: "cubic-bezier(0.18, 0.89, 0.32, 1.28)" } |  | 
|   75     ] |  | 
|   76 ] |  | 
|   77  |  | 
|   78 /** @typedef {{presets: !Array.<{name: string, value: string}>, icon: !Element, 
     presetIndex: number}} */ |  | 
|   79 WebInspector.BezierEditor.PresetCategory; |  | 
|   80  |  | 
|   81 WebInspector.BezierEditor.prototype = { |  | 
|   82     /** |  | 
|   83      * @param {?WebInspector.Geometry.CubicBezier} bezier |  | 
|   84      */ |  | 
|   85     setBezier: function(bezier) |  | 
|   86     { |  | 
|   87         if (!bezier) |  | 
|   88             return; |  | 
|   89         this._bezier = bezier; |  | 
|   90         this._updateUI(); |  | 
|   91     }, |  | 
|   92  |  | 
|   93     /** |  | 
|   94      * @return {!WebInspector.Geometry.CubicBezier} |  | 
|   95      */ |  | 
|   96     bezier: function() |  | 
|   97     { |  | 
|   98         return this._bezier; |  | 
|   99     }, |  | 
|  100  |  | 
|  101     wasShown: function() |  | 
|  102     { |  | 
|  103         this._unselectPresets(); |  | 
|  104         // Check if bezier matches a preset |  | 
|  105         for (var category of this._presetCategories) { |  | 
|  106             for (var i = 0; i < category.presets.length; i++) { |  | 
|  107                 if (this._bezier.asCSSText() === category.presets[i].value) { |  | 
|  108                     category.presetIndex = i; |  | 
|  109                     this._presetCategorySelected(category); |  | 
|  110                 } |  | 
|  111             } |  | 
|  112         } |  | 
|  113  |  | 
|  114         this._updateUI(); |  | 
|  115         this._startPreviewAnimation(); |  | 
|  116     }, |  | 
|  117  |  | 
|  118     _onchange: function() |  | 
|  119     { |  | 
|  120         this._updateUI(); |  | 
|  121         this.dispatchEventToListeners(WebInspector.BezierEditor.Events.BezierCha
     nged, this._bezier.asCSSText()); |  | 
|  122     }, |  | 
|  123  |  | 
|  124     _updateUI: function() |  | 
|  125     { |  | 
|  126         var labelText = this._selectedCategory ? this._selectedCategory.presets[
     this._selectedCategory.presetIndex].name : this._bezier.asCSSText().replace(/\s(
     -\d\.\d)/g, "$1"); |  | 
|  127         this._label.textContent = WebInspector.UIString(labelText); |  | 
|  128         this._curveUI.drawCurve(this._bezier, this._curve); |  | 
|  129         this._previewOnion.removeChildren(); |  | 
|  130     }, |  | 
|  131  |  | 
|  132     /** |  | 
|  133      * @param {!Event} event |  | 
|  134      * @return {boolean} |  | 
|  135      */ |  | 
|  136     _dragStart: function(event) |  | 
|  137     { |  | 
|  138         this._mouseDownPosition = new WebInspector.Geometry.Point(event.x, event
     .y); |  | 
|  139         var ui = this._curveUI; |  | 
|  140         this._controlPosition = new WebInspector.Geometry.Point( |  | 
|  141             Number.constrain((event.offsetX - ui.radius) / ui.curveWidth(), 0, 1
     ), |  | 
|  142             (ui.curveHeight() + ui.marginTop + ui.radius - event.offsetY) / ui.c
     urveHeight()); |  | 
|  143  |  | 
|  144         var firstControlPointIsCloser = this._controlPosition.distanceTo(this._b
     ezier.controlPoints[0]) < this._controlPosition.distanceTo(this._bezier.controlP
     oints[1]); |  | 
|  145         this._selectedPoint = firstControlPointIsCloser ? 0 : 1; |  | 
|  146  |  | 
|  147         this._bezier.controlPoints[this._selectedPoint] = this._controlPosition; |  | 
|  148         this._unselectPresets(); |  | 
|  149         this._onchange(); |  | 
|  150  |  | 
|  151         event.consume(true); |  | 
|  152         return true; |  | 
|  153     }, |  | 
|  154  |  | 
|  155     /** |  | 
|  156      * @param {number} mouseX |  | 
|  157      * @param {number} mouseY |  | 
|  158      */ |  | 
|  159     _updateControlPosition: function(mouseX, mouseY) |  | 
|  160     { |  | 
|  161         var deltaX = (mouseX - this._mouseDownPosition.x) / this._curveUI.curveW
     idth(); |  | 
|  162         var deltaY = (mouseY - this._mouseDownPosition.y) / this._curveUI.curveH
     eight(); |  | 
|  163         var newPosition = new WebInspector.Geometry.Point(Number.constrain(this.
     _controlPosition.x + deltaX, 0, 1), this._controlPosition.y - deltaY); |  | 
|  164         this._bezier.controlPoints[this._selectedPoint] = newPosition; |  | 
|  165     }, |  | 
|  166  |  | 
|  167     /** |  | 
|  168      * @param {!Event} event |  | 
|  169      */ |  | 
|  170     _dragMove: function(event) |  | 
|  171     { |  | 
|  172         this._updateControlPosition(event.x, event.y); |  | 
|  173         this._onchange(); |  | 
|  174     }, |  | 
|  175  |  | 
|  176     /** |  | 
|  177      * @param {!Event} event |  | 
|  178      */ |  | 
|  179     _dragEnd: function(event) |  | 
|  180     { |  | 
|  181         this._updateControlPosition(event.x, event.y); |  | 
|  182         this._onchange(); |  | 
|  183         this._startPreviewAnimation(); |  | 
|  184     }, |  | 
|  185  |  | 
|  186     /** |  | 
|  187      * @param {!Array<{name: string, value: string}>} presetGroup |  | 
|  188      * @return {!WebInspector.BezierEditor.PresetCategory} |  | 
|  189      */ |  | 
|  190     _createCategory: function(presetGroup) |  | 
|  191     { |  | 
|  192         var presetElement = createElementWithClass("div", "bezier-preset-categor
     y"); |  | 
|  193         var iconElement = presetElement.createSVGChild("svg", "bezier-preset mon
     ospace"); |  | 
|  194         var category = { presets: presetGroup, presetIndex: 0, icon: presetEleme
     nt }; |  | 
|  195         this._presetUI.drawCurve(WebInspector.Geometry.CubicBezier.parse(categor
     y.presets[0].value), iconElement); |  | 
|  196         iconElement.addEventListener("click", this._presetCategorySelected.bind(
     this, category)); |  | 
|  197         return category; |  | 
|  198     }, |  | 
|  199  |  | 
|  200     /** |  | 
|  201      * @param {!Element} parentElement |  | 
|  202      * @param {string} className |  | 
|  203      * @param {string} drawPath |  | 
|  204      * @return {!Element} |  | 
|  205      */ |  | 
|  206     _createPresetModifyIcon: function(parentElement, className, drawPath) |  | 
|  207     { |  | 
|  208         var icon = parentElement.createSVGChild("svg", "bezier-preset-modify " +
      className); |  | 
|  209         icon.setAttribute("width", 20); |  | 
|  210         icon.setAttribute("height", 20); |  | 
|  211         var path = icon.createSVGChild("path"); |  | 
|  212         path.setAttribute("d", drawPath); |  | 
|  213         return icon; |  | 
|  214     }, |  | 
|  215  |  | 
|  216     _unselectPresets: function() |  | 
|  217     { |  | 
|  218         for (var category of this._presetCategories) |  | 
|  219             category.icon.classList.remove("bezier-preset-selected"); |  | 
|  220         delete this._selectedCategory; |  | 
|  221         this._header.classList.remove("bezier-header-active"); |  | 
|  222     }, |  | 
|  223  |  | 
|  224     /** |  | 
|  225      * @param {!WebInspector.BezierEditor.PresetCategory} category |  | 
|  226      * @param {!Event=} event |  | 
|  227      */ |  | 
|  228     _presetCategorySelected: function(category, event) |  | 
|  229     { |  | 
|  230         if (this._selectedCategory === category) |  | 
|  231             return; |  | 
|  232         this._unselectPresets(); |  | 
|  233         this._header.classList.add("bezier-header-active"); |  | 
|  234         this._selectedCategory = category; |  | 
|  235         this._selectedCategory.icon.classList.add("bezier-preset-selected"); |  | 
|  236         this.setBezier(WebInspector.Geometry.CubicBezier.parse(category.presets[
     category.presetIndex].value)); |  | 
|  237         this._onchange(); |  | 
|  238         this._startPreviewAnimation(); |  | 
|  239         if (event) |  | 
|  240             event.consume(true); |  | 
|  241     }, |  | 
|  242  |  | 
|  243     /** |  | 
|  244      * @param {boolean} intensify |  | 
|  245      * @param {!Event} event |  | 
|  246      */ |  | 
|  247     _presetModifyClicked: function(intensify, event) |  | 
|  248     { |  | 
|  249         if (!this._selectedCategory) |  | 
|  250             return; |  | 
|  251  |  | 
|  252         var length = this._selectedCategory.presets.length; |  | 
|  253         this._selectedCategory.presetIndex = (this._selectedCategory.presetIndex
      + (intensify ? 1 : -1) + length) % length; |  | 
|  254         this.setBezier(WebInspector.Geometry.CubicBezier.parse(this._selectedCat
     egory.presets[this._selectedCategory.presetIndex].value)); |  | 
|  255         this._onchange(); |  | 
|  256         this._startPreviewAnimation(); |  | 
|  257     }, |  | 
|  258  |  | 
|  259     _startPreviewAnimation: function() |  | 
|  260     { |  | 
|  261         if (this._previewAnimation) |  | 
|  262             this._previewAnimation.cancel(); |  | 
|  263  |  | 
|  264         const animationDuration = 1600; |  | 
|  265         const numberOnionSlices = 20; |  | 
|  266  |  | 
|  267         var keyframes = [{ offset: 0, transform: "translateX(0px)", easing: this
     ._bezier.asCSSText(), opacity: 1 }, |  | 
|  268             { offset: 0.9, transform: "translateX(218px)", opacity: 1 }, |  | 
|  269             { offset: 1, transform: "translateX(218px)", opacity: 0 }]; |  | 
|  270         this._previewAnimation = this._previewElement.animate(keyframes, animati
     onDuration); |  | 
|  271         this._previewOnion.removeChildren(); |  | 
|  272         for (var i = 0; i <= numberOnionSlices; i++) { |  | 
|  273             var slice = this._previewOnion.createChild("div", "bezier-preview-an
     imation"); |  | 
|  274             var player = slice.animate([{ transform: "translateX(0px)", easing: 
     this._bezier.asCSSText() }, { transform: "translateX(218px)" }], |  | 
|  275                 { duration: animationDuration, fill: "forwards" }); |  | 
|  276             player.pause(); |  | 
|  277             player.currentTime = animationDuration * i / numberOnionSlices; |  | 
|  278         } |  | 
|  279     }, |  | 
|  280  |  | 
|  281     __proto__: WebInspector.VBox.prototype |  | 
|  282 } |  | 
| OLD | NEW |