Chromium Code Reviews| Index: Source/devtools/front_end/elements/AnimationTimeline.js |
| diff --git a/Source/devtools/front_end/elements/AnimationTimeline.js b/Source/devtools/front_end/elements/AnimationTimeline.js |
| index 70de76fbc9736c44260053c1331ac0648c4f5401..98a7c7f63c1afa02cad48c4d39834eec5d2a7407 100644 |
| --- a/Source/devtools/front_end/elements/AnimationTimeline.js |
| +++ b/Source/devtools/front_end/elements/AnimationTimeline.js |
| @@ -29,6 +29,8 @@ WebInspector.AnimationTimeline = function() |
| this._symbol = Symbol("animationTimeline"); |
| /** @type {!Map.<string, !WebInspector.AnimationModel.AnimationPlayer>} */ |
| this._animationsMap = new Map(); |
| + this._timelineBezierEditor = new WebInspector.AnimationTimeline.BezierEditor(); |
| + |
| WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this); |
| WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspector.DOMModel.Events.NodeRemoved, this._nodeRemoved, this); |
| @@ -571,6 +573,14 @@ WebInspector.AnimationTimeline.prototype = { |
| target.animationModel.setPlaybackRate(this._playbackRate()); |
| }, |
| + /** |
| + * @return {!WebInspector.AnimationTimeline.BezierEditor} |
| + */ |
| + bezierEditor: function() |
| + { |
| + return this._timelineBezierEditor; |
| + }, |
| + |
| __proto__: WebInspector.VBox.prototype |
| } |
| @@ -691,11 +701,18 @@ WebInspector.AnimationUI = function(animation, timeline, parentElement) { |
| this._nameElement = parentElement.createChild("div", "animation-name"); |
| this._nameElement.textContent = this._animation.name(); |
| + this._bezierIconElement = WebInspector.BezierPopoverIcon.createIcon(parentElement); |
| + this._bezierIconElement.style.backgroundColor = this._color(); |
| + var editor = this._timeline.bezierEditor(); |
| + this._bezierIconElement.addEventListener("mousedown", editor.toggle.bind(editor, this, this._bezierIconElement)); |
| + |
| this._svg = parentElement.createSVGChild("svg", "animation-ui"); |
| this._svg.setAttribute("height", WebInspector.AnimationUI.Options.AnimationSVGHeight); |
| this._svg.style.marginLeft = "-" + WebInspector.AnimationUI.Options.AnimationMargin + "px"; |
| this._svg.addEventListener("mousedown", this._mouseDown.bind(this, WebInspector.AnimationUI.MouseEvents.AnimationDrag, null)); |
| this._activeIntervalGroup = this._svg.createSVGChild("g"); |
| + this._activeIntervalGroup.addEventListener("mouseover", this._toggleBezierIcon.bind(this, true)); |
| + this._activeIntervalGroup.addEventListener("mouseout", this._toggleBezierIcon.bind(this, false)); |
| /** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints: !Object.<number, !Element>, keyframeRender: !Object.<number, !Element>}>} */ |
| this._cachedElements = []; |
| @@ -868,7 +885,9 @@ WebInspector.AnimationUI.prototype = { |
| this._svg.style.transform = "translateX(" + leftMargin.toFixed(2) + "px)"; |
| this._activeIntervalGroup.style.transform = "translateX(" + (this._delay() * this._timeline.pixelMsRatio()).toFixed(2) + "px)"; |
| - this._nameElement.style.transform = "translateX(" + (leftMargin + this._delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2) + "px)"; |
| + var leftPosition = (leftMargin + this._delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2); |
| + this._nameElement.style.transform = "translateX(" + leftPosition + "px)"; |
| + this._bezierIconElement.style.marginLeft = leftPosition + "px"; |
| this._nameElement.style.width = (this._duration() * this._timeline.pixelMsRatio().toFixed(2)) + "px"; |
| this._drawDelayLine(this._svg); |
| @@ -887,7 +906,6 @@ WebInspector.AnimationUI.prototype = { |
| this._cachedElements.pop().group.remove(); |
| }, |
| - |
| _renderTransition: function() |
| { |
| if (!this._cachedElements[0]) |
| @@ -1030,6 +1048,39 @@ WebInspector.AnimationUI.prototype = { |
| }, |
| /** |
| + * @param {boolean} show |
| + */ |
| + _toggleBezierIcon: function(show) |
| + { |
| + var bezier = WebInspector.Geometry.CubicBezier.parse(this._animation.source().easing()); |
| + if (show && (this._animation.playState() === "idle" || !bezier)) |
| + return; |
| + this._bezierIconElement.classList.toggle("shown", show); |
| + }, |
| + |
| + /** |
| + * @param {string} value |
| + */ |
| + _setEasing: function(value) |
| + { |
| + if (!this._node || this._animation.source().easing() == value) |
|
dgozman
2015/05/26 12:02:23
===
samli
2015/05/27 05:21:59
Done.
|
| + return; |
| + |
| + this._animation.source().setEasing(value); |
| + this.redraw(); |
| + |
| + var animationType = this._animation.type(); |
| + if (animationType !== "CSSAnimation") { |
| + var target = WebInspector.targetManager.mainTarget(); |
| + if (target) |
| + target.animationAgent().setEasing(this._animation.id(), value); |
|
dgozman
2015/05/26 12:02:23
UI should not call animationAgent() and operate wi
samli
2015/05/27 05:21:59
Ack.
|
| + } |
| + |
| + if (animationType !== "WebAnimation") |
| + this._setNodeStyle(animationType === "CSSTransition" ? "transition-timing-function" : "animation-timing-function", value); |
| + }, |
| + |
| + /** |
| * @param {number} value |
| */ |
| _setDelay: function(value) |
| @@ -1077,7 +1128,7 @@ WebInspector.AnimationUI.prototype = { |
| if (style) |
| style = style.replace(new RegExp("\\s*(-webkit-)?" + name + ":[^;]*;?\\s*", "g"), ""); |
| var valueString = name + ": " + value; |
| - this._node.setAttributeValue("style", style + " " + valueString + "; -webkit-" + valueString + ";"); |
| + this._node.setAttributeValue("style", style + " " + valueString + ";"); |
| }, |
| /** |
| @@ -1126,3 +1177,106 @@ WebInspector.AnimationUI.Colors = { |
| "Brown": WebInspector.Color.parse("#795548"), |
| "Cyan": WebInspector.Color.parse("#00BCD4") |
| } |
| + |
| +/** |
| + * @constructor |
| + */ |
| +WebInspector.AnimationTimeline.BezierEditor = function() |
| +{ |
| + this._popover = new WebInspector.Popover(); |
| + this._popover.setCanShrink(false); |
| + this._popover.setNoMargins(true); |
| + this._bezierEditor = new WebInspector.BezierEditor(); |
| + this._boundOnKeyDown = this._onKeyDown.bind(this); |
| + this._boundOnFocusOut = this._onFocusOut.bind(this); |
| +} |
| + |
| +WebInspector.AnimationTimeline.BezierEditor.prototype = { |
|
dgozman
2015/05/26 12:02:23
That's quite a lot of code duplication. Perhaps, w
samli
2015/05/27 05:21:59
Reluctantly done.
|
| + /** |
| + * @param {!WebInspector.AnimationUI} animationUI |
| + * @param {!Element} anchorElement |
| + * @param {!Event} event |
| + */ |
| + toggle: function(animationUI, anchorElement, event) |
| + { |
| + var shouldShow = !this._popover.isShowing() || this._animationUI !== animationUI; |
| + if (this._popover.isShowing()) |
| + this._hide(true); |
| + if (shouldShow) |
| + this._show(animationUI, anchorElement, event); |
| + event.stopPropagation(); |
| + event.preventDefault(); |
| + }, |
| + |
| + /** |
| + * @param {!WebInspector.AnimationUI} animationUI |
| + * @param {!Element} anchorElement |
| + * @param {!Event} event |
| + */ |
| + _show: function(animationUI, anchorElement, event) |
| + { |
| + this._animationUI = animationUI; |
| + this._anchorElement = anchorElement; |
| + this._previousFocusElement = WebInspector.currentFocusElement(); |
| + |
| + this._originalEasing = this._animationUI.animation().source().easing(); |
| + var bezier = WebInspector.Geometry.CubicBezier.parse(this._originalEasing); |
| + this._bezierEditor.setBezier(bezier); |
| + this._bezierEditor.addEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._bezierChanged, this); |
| + this._popover.showView(this._bezierEditor, this._anchorElement); |
| + this._bezierEditor.contentElement.addEventListener("keydown", this._boundOnKeyDown); |
| + this._bezierEditor.contentElement.addEventListener("focusout", this._boundOnFocusOut); |
| + this._anchorElement.classList.add("bezier-editor-open"); |
| + WebInspector.setCurrentFocusElement(this._bezierEditor.contentElement); |
| + }, |
| + |
| + /** |
| + * @param {boolean=} commitEdit |
| + */ |
| + _hide: function(commitEdit) |
| + { |
| + if (!this._popover.isShowing()) |
| + return; |
| + this._anchorElement.classList.remove("bezier-editor-open"); |
| + this._bezierEditor.removeEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._bezierChanged, this); |
| + if (!commitEdit) |
| + this._animationUI._setEasing(this._originalEasing); |
| + this._popover.hide(); |
| + this._bezierEditor.detach(); |
| + this._bezierEditor.contentElement.removeEventListener("keydown", this._boundOnKeyDown); |
| + this._bezierEditor.contentElement.removeEventListener("focusout", this._boundOnFocusOut); |
| + WebInspector.setCurrentFocusElement(this._previousFocusElement); |
| + }, |
| + |
| + /** |
| + * @param {!Event} event |
| + */ |
| + _onFocusOut: function(event) |
| + { |
| + this._hide(true); |
| + }, |
| + |
| + /** |
| + * @param {!Event} event |
| + */ |
| + _onKeyDown: function(event) |
| + { |
| + if (event.keyIdentifier === "Enter") { |
| + this._hide(true); |
| + event.consume(true); |
| + return; |
| + } |
| + if (event.keyIdentifier === "U+001B") { // Escape key |
| + this._hide(false); |
| + event.consume(true); |
| + } |
| + }, |
| + |
| + /** |
| + * @param {!WebInspector.Event} event |
| + */ |
| + _bezierChanged: function(event) |
| + { |
| + this._animationUI._setEasing(/** @type {string} */ (event.data)); |
| + } |
| +} |