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

Side by Side 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: Missing files 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.VBox} 7 * @extends {WebInspector.VBox}
8 * @implements {WebInspector.TargetManager.Observer} 8 * @implements {WebInspector.TargetManager.Observer}
9 */ 9 */
10 WebInspector.AnimationTimeline = function() 10 WebInspector.AnimationTimeline = function()
(...skipping 11 matching lines...) Expand all
22 this.contentElement.appendChild(this._createHeader()); 22 this.contentElement.appendChild(this._createHeader());
23 this._animationsContainer = this.contentElement.createChild("div", "animatio n-timeline-rows"); 23 this._animationsContainer = this.contentElement.createChild("div", "animatio n-timeline-rows");
24 this._duration = this._defaultDuration(); 24 this._duration = this._defaultDuration();
25 this._scrubberRadius = 25; 25 this._scrubberRadius = 25;
26 this._timelineControlsWidth = 200; 26 this._timelineControlsWidth = 200;
27 /** @type {!Map.<!DOMAgent.BackendNodeId, !WebInspector.AnimationTimeline.No deUI>} */ 27 /** @type {!Map.<!DOMAgent.BackendNodeId, !WebInspector.AnimationTimeline.No deUI>} */
28 this._nodesMap = new Map(); 28 this._nodesMap = new Map();
29 this._symbol = Symbol("animationTimeline"); 29 this._symbol = Symbol("animationTimeline");
30 /** @type {!Map.<string, !WebInspector.AnimationModel.AnimationPlayer>} */ 30 /** @type {!Map.<string, !WebInspector.AnimationModel.AnimationPlayer>} */
31 this._animationsMap = new Map(); 31 this._animationsMap = new Map();
32 this._editorPopoverHelper = new WebInspector.EditorPopoverHelper();
33 this._bezierEditor = new WebInspector.BezierEditor();
34
32 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNav igated, this); 35 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNav igated, this);
33 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspec tor.DOMModel.Events.NodeRemoved, this._nodeRemoved, this); 36 WebInspector.targetManager.addModelListener(WebInspector.DOMModel, WebInspec tor.DOMModel.Events.NodeRemoved, this._nodeRemoved, this);
34 37
35 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Pag e); 38 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Type.Pag e);
36 } 39 }
37 40
38 WebInspector.AnimationTimeline.GlobalPlaybackRates = [0.1, 0.25, 0.5, 1.0]; 41 WebInspector.AnimationTimeline.GlobalPlaybackRates = [0.1, 0.25, 0.5, 1.0];
39 42
40 WebInspector.AnimationTimeline.prototype = { 43 WebInspector.AnimationTimeline.prototype = {
41 wasShown: function() 44 wasShown: function()
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 */ 593 */
591 WebInspector.AnimationTimeline.NodeUI = function(animationNode) { 594 WebInspector.AnimationTimeline.NodeUI = function(animationNode) {
592 /** 595 /**
593 * @param {?WebInspector.DOMNode} node 596 * @param {?WebInspector.DOMNode} node
594 * @this {WebInspector.AnimationTimeline.NodeUI} 597 * @this {WebInspector.AnimationTimeline.NodeUI}
595 */ 598 */
596 function nodeResolved(node) 599 function nodeResolved(node)
597 { 600 {
598 this._node = node; 601 this._node = node;
599 this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyN odeReference(node)); 602 this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyN odeReference(node));
600 this.element.addEventListener("click", WebInspector.Revealer.reveal.bind (WebInspector.Revealer, node, undefined), false); 603 this.element.addEventListener("mousedown", WebInspector.Revealer.reveal. bind(WebInspector.Revealer, node, undefined), false);
601 } 604 }
602 605
603 this._rows = []; 606 this._rows = [];
604 this.element = createElementWithClass("div", "animation-node-row"); 607 this.element = createElementWithClass("div", "animation-node-row");
605 this._description = this.element.createChild("div", "animation-node-descript ion"); 608 this._description = this.element.createChild("div", "animation-node-descript ion");
606 animationNode.deferredNode().resolve(nodeResolved.bind(this)); 609 animationNode.deferredNode().resolve(nodeResolved.bind(this));
607 this._timelineElement = this.element.createChild("div", "animation-node-time line"); 610 this._timelineElement = this.element.createChild("div", "animation-node-time line");
608 } 611 }
609 612
610 /** @typedef {{element: !Element, animations: !Array<!WebInspector.AnimationUI>} } */ 613 /** @typedef {{element: !Element, animations: !Array<!WebInspector.AnimationUI>} } */
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 this._animation = animation; 707 this._animation = animation;
705 this._timeline = timeline; 708 this._timeline = timeline;
706 this._parentElement = parentElement; 709 this._parentElement = parentElement;
707 710
708 if (this._animation.source().keyframesRule()) 711 if (this._animation.source().keyframesRule())
709 this._keyframes = this._animation.source().keyframesRule().keyframes(); 712 this._keyframes = this._animation.source().keyframesRule().keyframes();
710 713
711 this._nameElement = parentElement.createChild("div", "animation-name"); 714 this._nameElement = parentElement.createChild("div", "animation-name");
712 this._nameElement.textContent = this._animation.name(); 715 this._nameElement.textContent = this._animation.name();
713 716
717 this._bezierIconElement = WebInspector.BezierPopoverIcon.createIcon(parentEl ement);
718 this._bezierIconElement.style.backgroundColor = this._color();
719 this._bezierIconElement.addEventListener("mousedown", this._toggleBezierEdit or.bind(this));
720
714 this._svg = parentElement.createSVGChild("svg", "animation-ui"); 721 this._svg = parentElement.createSVGChild("svg", "animation-ui");
715 this._svg.setAttribute("height", WebInspector.AnimationUI.Options.AnimationS VGHeight); 722 this._svg.setAttribute("height", WebInspector.AnimationUI.Options.AnimationS VGHeight);
716 this._svg.style.marginLeft = "-" + WebInspector.AnimationUI.Options.Animatio nMargin + "px"; 723 this._svg.style.marginLeft = "-" + WebInspector.AnimationUI.Options.Animatio nMargin + "px";
717 this._svg.addEventListener("mousedown", this._mouseDown.bind(this, WebInspec tor.AnimationUI.MouseEvents.AnimationDrag, null)); 724 this._svg.addEventListener("mousedown", this._mouseDown.bind(this, WebInspec tor.AnimationUI.MouseEvents.AnimationDrag, null));
718 this._activeIntervalGroup = this._svg.createSVGChild("g"); 725 this._activeIntervalGroup = this._svg.createSVGChild("g");
726 this._activeIntervalGroup.addEventListener("mouseover", this._toggleBezierIc on.bind(this, true));
727 this._activeIntervalGroup.addEventListener("mouseout", this._toggleBezierIco n.bind(this, false));
719 728
720 /** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints : !Object.<number, !Element>, keyframeRender: !Object.<number, !Element>}>} */ 729 /** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints : !Object.<number, !Element>, keyframeRender: !Object.<number, !Element>}>} */
721 this._cachedElements = []; 730 this._cachedElements = [];
722 731
723 this._movementInMs = 0; 732 this._movementInMs = 0;
724 this.redraw(); 733 this.redraw();
725 } 734 }
726 735
727 /** 736 /**
728 * @enum {string} 737 * @enum {string}
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 var durationWithDelay = this._delay() + this._duration() * this._animati on.source().iterations() + this._animation.source().endDelay(); 890 var durationWithDelay = this._delay() + this._duration() * this._animati on.source().iterations() + this._animation.source().endDelay();
882 var leftMargin = ((this._animation.startTime() - this._timeline.startTim e()) * this._timeline.pixelMsRatio()); 891 var leftMargin = ((this._animation.startTime() - this._timeline.startTim e()) * this._timeline.pixelMsRatio());
883 var maxWidth = this._timeline.width() - WebInspector.AnimationUI.Options .AnimationMargin - leftMargin; 892 var maxWidth = this._timeline.width() - WebInspector.AnimationUI.Options .AnimationMargin - leftMargin;
884 var svgWidth = Math.min(maxWidth, durationWithDelay * this._timeline.pix elMsRatio()); 893 var svgWidth = Math.min(maxWidth, durationWithDelay * this._timeline.pix elMsRatio());
885 894
886 this._svg.classList.toggle("animation-ui-canceled", this._animation.play State() === "idle"); 895 this._svg.classList.toggle("animation-ui-canceled", this._animation.play State() === "idle");
887 this._svg.setAttribute("width", (svgWidth + 2 * WebInspector.AnimationUI .Options.AnimationMargin).toFixed(2)); 896 this._svg.setAttribute("width", (svgWidth + 2 * WebInspector.AnimationUI .Options.AnimationMargin).toFixed(2));
888 this._svg.style.transform = "translateX(" + leftMargin.toFixed(2) + "px )"; 897 this._svg.style.transform = "translateX(" + leftMargin.toFixed(2) + "px )";
889 this._activeIntervalGroup.style.transform = "translateX(" + (this._delay () * this._timeline.pixelMsRatio()).toFixed(2) + "px)"; 898 this._activeIntervalGroup.style.transform = "translateX(" + (this._delay () * this._timeline.pixelMsRatio()).toFixed(2) + "px)";
890 899
891 this._nameElement.style.transform = "translateX(" + (leftMargin + this._ delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.Anima tionMargin).toFixed(2) + "px)"; 900 var leftPosition = (leftMargin + this._delay() * this._timeline.pixelMsR atio() + WebInspector.AnimationUI.Options.AnimationMargin).toFixed(2);
901 this._nameElement.style.transform = "translateX(" + leftPosition + "px)" ;
902 this._bezierIconElement.style.marginLeft = leftPosition + "px";
892 this._nameElement.style.width = (this._duration() * this._timeline.pixel MsRatio().toFixed(2)) + "px"; 903 this._nameElement.style.width = (this._duration() * this._timeline.pixel MsRatio().toFixed(2)) + "px";
893 this._drawDelayLine(this._svg); 904 this._drawDelayLine(this._svg);
894 905
895 if (this._animation.type() === "CSSTransition") { 906 if (this._animation.type() === "CSSTransition") {
896 this._renderTransition(); 907 this._renderTransition();
897 return; 908 return;
898 } 909 }
899 910
900 this._renderIteration(this._activeIntervalGroup, 0); 911 this._renderIteration(this._activeIntervalGroup, 0);
901 if (!this._tailGroup) 912 if (!this._tailGroup)
902 this._tailGroup = this._activeIntervalGroup.createSVGChild("g", "ani mation-tail-iterations"); 913 this._tailGroup = this._activeIntervalGroup.createSVGChild("g", "ani mation-tail-iterations");
903 var iterationWidth = this._duration() * this._timeline.pixelMsRatio(); 914 var iterationWidth = this._duration() * this._timeline.pixelMsRatio();
904 for (var iteration = 1; iteration < this._animation.source().iterations( ) && iterationWidth * (iteration - 1) < this._timeline.width(); iteration++) 915 for (var iteration = 1; iteration < this._animation.source().iterations( ) && iterationWidth * (iteration - 1) < this._timeline.width(); iteration++)
905 this._renderIteration(this._tailGroup, iteration); 916 this._renderIteration(this._tailGroup, iteration);
906 while (iteration < this._cachedElements.length) 917 while (iteration < this._cachedElements.length)
907 this._cachedElements.pop().group.remove(); 918 this._cachedElements.pop().group.remove();
908 }, 919 },
909 920
910
911 _renderTransition: function() 921 _renderTransition: function()
912 { 922 {
913 if (!this._cachedElements[0]) 923 if (!this._cachedElements[0])
914 this._cachedElements[0] = { animationLine: null, keyframePoints: {}, keyframeRender: {}, group: null }; 924 this._cachedElements[0] = { animationLine: null, keyframePoints: {}, keyframeRender: {}, group: null };
915 this._drawAnimationLine(0, this._activeIntervalGroup); 925 this._drawAnimationLine(0, this._activeIntervalGroup);
916 this._renderKeyframe(0, 0, this._activeIntervalGroup, WebInspector.Anima tionUI.Options.AnimationMargin, this._duration() * this._timeline.pixelMsRatio() , this._animation.source().easing()); 926 this._renderKeyframe(0, 0, this._activeIntervalGroup, WebInspector.Anima tionUI.Options.AnimationMargin, this._duration() * this._timeline.pixelMsRatio() , this._animation.source().easing());
917 this._drawPoint(0, this._activeIntervalGroup, WebInspector.AnimationUI.O ptions.AnimationMargin, 0, true); 927 this._drawPoint(0, this._activeIntervalGroup, WebInspector.AnimationUI.O ptions.AnimationMargin, 0, true);
918 this._drawPoint(0, this._activeIntervalGroup, this._duration() * this._t imeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin, -1, t rue); 928 this._drawPoint(0, this._activeIntervalGroup, this._duration() * this._t imeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin, -1, t rue);
919 }, 929 },
920 930
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 this._parentElement.ownerDocument.removeEventListener("mousemove", this. _mouseMoveHandler); 1053 this._parentElement.ownerDocument.removeEventListener("mousemove", this. _mouseMoveHandler);
1044 this._parentElement.ownerDocument.removeEventListener("mouseup", this._m ouseUpHandler); 1054 this._parentElement.ownerDocument.removeEventListener("mouseup", this._m ouseUpHandler);
1045 delete this._mouseMoveHandler; 1055 delete this._mouseMoveHandler;
1046 delete this._mouseUpHandler; 1056 delete this._mouseUpHandler;
1047 delete this._mouseEventType; 1057 delete this._mouseEventType;
1048 delete this._downMouseX; 1058 delete this._downMouseX;
1049 delete this._keyframeMoved; 1059 delete this._keyframeMoved;
1050 }, 1060 },
1051 1061
1052 /** 1062 /**
1063 * @param {boolean} show
1064 */
1065 _toggleBezierIcon: function(show)
dgozman 2015/05/28 11:04:03 Code below this line looks like exact copy of Bezi
samli 2015/05/29 04:32:11 This function is not in BezierPopoverIcon. Bezier
1066 {
1067 var bezier = WebInspector.Geometry.CubicBezier.parse(this._animation.sou rce().easing());
1068 if (show && (this._animation.playState() === "idle" || !bezier))
1069 return;
1070 this._bezierIconElement.classList.toggle("shown", show);
1071 },
1072
1073 /**
1074 * @param {!Event} event
1075 */
1076 _toggleBezierEditor: function(event)
1077 {
1078 var popover = this._timeline._editorPopoverHelper;
1079 var shouldShow = !popover.isShowing() || this._bezierIconElement !== pop over.anchorElement();
1080
1081 if (popover.isShowing())
1082 popover.hide();
1083
1084 if (shouldShow) {
1085 this._originalEasing = this._animation.source().easing();
1086 var bezier = WebInspector.Geometry.CubicBezier.parse(this._originalE asing);
1087 this._timeline._bezierEditor.setBezier(bezier);
1088 this._timeline._bezierEditor.addEventListener(WebInspector.BezierEdi tor.Events.BezierChanged, this._bezierChanged, this);
1089 popover.show(this._timeline._bezierEditor, this._bezierIconElement, this._onPopoverHidden.bind(this));
1090 this._bezierIconElement.classList.add("bezier-editor-open");
1091 }
1092
1093 event.stopPropagation();
1094 event.preventDefault();
1095 },
1096
1097 /**
1098 * @param {!WebInspector.Event} event
1099 */
1100 _bezierChanged: function(event)
1101 {
1102 this._setEasing(/** @type {string} */ (event.data));
1103 },
1104
1105 /**
1106 * @param {boolean} commitEdit
1107 */
1108 _onPopoverHidden: function(commitEdit)
1109 {
1110 this._bezierIconElement.classList.remove("bezier-editor-open");
1111 this._timeline._bezierEditor.removeEventListener(WebInspector.BezierEdit or.Events.BezierChanged, this._bezierChanged, this);
1112 if (!commitEdit)
1113 this._setEasing(this._originalEasing);
1114 },
1115
1116 /**
1117 * @param {string} value
1118 */
1119 _setEasing: function(value)
1120 {
1121 if (!this._node || this._animation.source().easing() === value)
1122 return;
1123
1124 this._animation.source().setEasing(value, this._animation.id(), this._an imation.type() !== "CSSAnimation");
1125 this.redraw();
1126
1127 if (this._animation.type() !== "WebAnimation")
1128 this._setNodeStyle(this._animation.type() === "CSSTransition" ? "tra nsition-timing-function" : "animation-timing-function", value);
1129 },
1130
1131 /**
1053 * @param {number} value 1132 * @param {number} value
1054 */ 1133 */
1055 _setDelay: function(value) 1134 _setDelay: function(value)
1056 { 1135 {
1057 if (!this._node || this._animation.source().delay() == this._delay()) 1136 if (!this._node || this._animation.source().delay() == this._delay())
1058 return; 1137 return;
1059 1138
1060 this._animation.source().setDelay(this._delay()); 1139 this._animation.source().setDelay(this._delay());
1061 var propertyName; 1140 var propertyName;
1062 if (this._animation.type() == "CSSTransition") 1141 if (this._animation.type() == "CSSTransition")
(...skipping 27 matching lines...) Expand all
1090 /** 1169 /**
1091 * @param {string} name 1170 * @param {string} name
1092 * @param {string} value 1171 * @param {string} value
1093 */ 1172 */
1094 _setNodeStyle: function(name, value) 1173 _setNodeStyle: function(name, value)
1095 { 1174 {
1096 var style = this._node.getAttribute("style") || ""; 1175 var style = this._node.getAttribute("style") || "";
1097 if (style) 1176 if (style)
1098 style = style.replace(new RegExp("\\s*(-webkit-)?" + name + ":[^;]*; ?\\s*", "g"), ""); 1177 style = style.replace(new RegExp("\\s*(-webkit-)?" + name + ":[^;]*; ?\\s*", "g"), "");
1099 var valueString = name + ": " + value; 1178 var valueString = name + ": " + value;
1100 this._node.setAttributeValue("style", style + " " + valueString + "; -we bkit-" + valueString + ";"); 1179 this._node.setAttributeValue("style", style + " " + valueString + ";");
1101 }, 1180 },
1102 1181
1103 /** 1182 /**
1104 * @return {string} 1183 * @return {string}
1105 */ 1184 */
1106 _color: function() 1185 _color: function()
1107 { 1186 {
1108 /** 1187 /**
1109 * @param {string} string 1188 * @param {string} string
1110 * @return {number} 1189 * @return {number}
(...skipping 28 matching lines...) Expand all
1139 "Light Blue": WebInspector.Color.parse("#03A9F4"), 1218 "Light Blue": WebInspector.Color.parse("#03A9F4"),
1140 "Deep Orange": WebInspector.Color.parse("#FF5722"), 1219 "Deep Orange": WebInspector.Color.parse("#FF5722"),
1141 "Blue": WebInspector.Color.parse("#5677FC"), 1220 "Blue": WebInspector.Color.parse("#5677FC"),
1142 "Lime": WebInspector.Color.parse("#CDDC39"), 1221 "Lime": WebInspector.Color.parse("#CDDC39"),
1143 "Blue Grey": WebInspector.Color.parse("#607D8B"), 1222 "Blue Grey": WebInspector.Color.parse("#607D8B"),
1144 "Pink": WebInspector.Color.parse("#E91E63"), 1223 "Pink": WebInspector.Color.parse("#E91E63"),
1145 "Green": WebInspector.Color.parse("#0F9D58"), 1224 "Green": WebInspector.Color.parse("#0F9D58"),
1146 "Brown": WebInspector.Color.parse("#795548"), 1225 "Brown": WebInspector.Color.parse("#795548"),
1147 "Cyan": WebInspector.Color.parse("#00BCD4") 1226 "Cyan": WebInspector.Color.parse("#00BCD4")
1148 } 1227 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698