Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1233)

Unified Diff: Source/devtools/front_end/elements/AnimationTimeline.js

Issue 1155773002: Devtools Animations: Add cubic bezier easing editor for animations (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Remove empty line Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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));
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698