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

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: Rebase Created 5 years, 6 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
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/elements/BezierUI.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 fd80fb78fb60ac34ace1834bd7d3e62c2588e184..6adab8539ee655e5f101295b55a756f377657fcf 100644
--- a/Source/devtools/front_end/elements/AnimationTimeline.js
+++ b/Source/devtools/front_end/elements/AnimationTimeline.js
@@ -29,6 +29,9 @@ WebInspector.AnimationTimeline = function()
this._symbol = Symbol("animationTimeline");
/** @type {!Map.<string, !WebInspector.AnimationModel.AnimationPlayer>} */
this._animationsMap = new Map();
+ this._editorPopoverHelper = new WebInspector.EditorPopoverHelper();
+ this._bezierEditor = new WebInspector.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);
@@ -622,7 +625,7 @@ WebInspector.AnimationTimeline.NodeUI = function(animationNode) {
{
this._node = node;
this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeReference(node));
- this.element.addEventListener("click", WebInspector.Revealer.reveal.bind(WebInspector.Revealer, node, undefined), false);
+ this.element.addEventListener("mousedown", WebInspector.Revealer.reveal.bind(WebInspector.Revealer, node, undefined), false);
}
this._rows = [];
@@ -730,17 +733,20 @@ WebInspector.AnimationUI = function(animation, timeline, parentElement) {
this._timeline = timeline;
this._parentElement = parentElement;
- if (this._animation.source().keyframesRule())
- this._keyframes = this._animation.source().keyframesRule().keyframes();
-
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();
+ this._bezierIconElement.addEventListener("mousedown", this._toggleBezierEditor.bind(this));
+
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 = [];
@@ -769,6 +775,14 @@ WebInspector.AnimationUI.prototype = {
},
/**
+ * @return {?Array.<!WebInspector.AnimationModel.KeyframeStyle>}
+ */
+ _keyframes: function()
+ {
+ return this._animation.source().keyframesRule() ? this._animation.source().keyframesRule().keyframes() : null;
+ },
+
+ /**
* @param {?WebInspector.DOMNode} node
*/
setNode: function(node)
@@ -913,7 +927,10 @@ 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.classList.toggle("hidden", this._animation.playState() === "idle");
+ this._bezierIconElement.style.marginLeft = leftPosition + "px";
this._nameElement.style.width = (this._duration() * this._timeline.pixelMsRatio().toFixed(2)) + "px";
this._drawDelayLine(this._svg);
@@ -932,7 +949,6 @@ WebInspector.AnimationUI.prototype = {
this._cachedElements.pop().group.remove();
},
-
_renderTransition: function()
{
if (!this._cachedElements[0])
@@ -954,11 +970,11 @@ WebInspector.AnimationUI.prototype = {
var group = this._cachedElements[iteration].group;
group.style.transform = "translateX(" + (iteration * this._duration() * this._timeline.pixelMsRatio()).toFixed(2) + "px)";
this._drawAnimationLine(iteration, group);
- console.assert(this._keyframes.length > 1);
- for (var i = 0; i < this._keyframes.length - 1; i++) {
+ console.assert(this._keyframes().length > 1);
+ for (var i = 0; i < this._keyframes().length - 1; i++) {
var leftDistance = this._offset(i) * this._duration() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin;
var width = this._duration() * (this._offset(i + 1) - this._offset(i)) * this._timeline.pixelMsRatio();
- this._renderKeyframe(iteration, i, group, leftDistance, width, this._keyframes[i].easing());
+ this._renderKeyframe(iteration, i, group, leftDistance, width, this._keyframes()[i].easing());
if (i || (!i && iteration === 0))
this._drawPoint(iteration, group, leftDistance, i, iteration === 0);
}
@@ -996,12 +1012,12 @@ WebInspector.AnimationUI.prototype = {
*/
_offset: function(i)
{
- var offset = this._keyframes[i].offsetAsNumber();
+ var offset = this._keyframes()[i].offsetAsNumber();
if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.KeyframeMove && i === this._keyframeMoved) {
- console.assert(i > 0 && i < this._keyframes.length - 1, "First and last keyframe cannot be moved");
+ console.assert(i > 0 && i < this._keyframes().length - 1, "First and last keyframe cannot be moved");
offset += this._movementInMs / this._animation.source().duration();
- offset = Math.max(offset, this._keyframes[i - 1].offsetAsNumber());
- offset = Math.min(offset, this._keyframes[i + 1].offsetAsNumber());
+ offset = Math.max(offset, this._keyframes()[i - 1].offsetAsNumber());
+ offset = Math.min(offset, this._keyframes()[i + 1].offsetAsNumber());
}
return offset;
},
@@ -1049,7 +1065,7 @@ WebInspector.AnimationUI.prototype = {
// Commit changes
if (this._mouseEventType === WebInspector.AnimationUI.MouseEvents.KeyframeMove)
- this._keyframes[this._keyframeMoved].setOffset(this._offset(this._keyframeMoved));
+ this._keyframes()[this._keyframeMoved].setOffset(this._offset(this._keyframeMoved));
else
this._animation.setTiming(this._delay(), this._duration());
@@ -1065,6 +1081,69 @@ WebInspector.AnimationUI.prototype = {
},
/**
+ * @param {boolean} show
+ */
+ _toggleBezierIcon: function(show)
+ {
+ var bezier = WebInspector.Geometry.CubicBezier.parse(this._animation.source().easing());
+ if (show && !bezier)
+ return;
+ this._bezierIconElement.classList.toggle("shown", show);
+ },
+
+ /**
+ * @param {!Event} event
+ */
+ _toggleBezierEditor: function(event)
+ {
+ var popover = this._timeline._editorPopoverHelper;
+ var shouldShow = !popover.isShowing() || this._bezierIconElement !== popover.anchorElement();
+
+ if (popover.isShowing())
+ popover.hide();
+
+ if (shouldShow) {
+ this._originalEasing = this._animation.source().easing();
+ var bezier = WebInspector.Geometry.CubicBezier.parse(this._originalEasing);
+ this._timeline._bezierEditor.setBezier(bezier);
+ this._timeline._bezierEditor.addEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._bezierChanged, this);
+ var scrollerElement = this._bezierIconElement.enclosingNodeOrSelfWithClass(".animation-timeline-rows");
+ popover.show(this._timeline._bezierEditor, this._bezierIconElement, scrollerElement, this._onPopoverHidden.bind(this));
+ this._bezierIconElement.classList.add("bezier-editor-open");
+ }
+ event.consume(true);
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _bezierChanged: function(event)
+ {
+ this._setEasing(/** @type {string} */ (event.data));
+ },
+
+ /**
+ * @param {boolean} commitEdit
+ */
+ _onPopoverHidden: function(commitEdit)
+ {
+ this._bezierIconElement.classList.remove("bezier-editor-open");
+ this._timeline._bezierEditor.removeEventListener(WebInspector.BezierEditor.Events.BezierChanged, this._bezierChanged, this);
+ if (!commitEdit)
+ this._setEasing(this._originalEasing);
+ },
+
+ /**
+ * @param {string} value
+ */
+ _setEasing: function(value)
+ {
+ if (!this._node || this._animation.source().easing() === value)
+ return;
+ this._animation.setEasing(value);
+ },
+
+ /**
* @return {string}
*/
_color: function()
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/elements/BezierUI.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698