| 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()
|
|
|