Index: Source/devtools/front_end/elements/AnimationsSidebarPane.js |
diff --git a/Source/devtools/front_end/elements/AnimationsSidebarPane.js b/Source/devtools/front_end/elements/AnimationsSidebarPane.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3cd92c925dc1ef6aecf2577709db14e0f9672097 |
--- /dev/null |
+++ b/Source/devtools/front_end/elements/AnimationsSidebarPane.js |
@@ -0,0 +1,221 @@ |
+// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @constructor |
+ * @extends {WebInspector.SidebarPane} |
+ */ |
+WebInspector.AnimationsSidebarPane = function(stylesPane) |
+{ |
+ WebInspector.SidebarPane.call(this, WebInspector.UIString("Animations")); |
+ this._stylesPane = stylesPane; |
+ |
+ this._emptyElement = document.createElement("div"); |
+ this._emptyElement.className = "info"; |
+ this._emptyElement.textContent = WebInspector.UIString("No Animations"); |
+ |
+ this.bodyElement.appendChild(this._emptyElement); |
+} |
+ |
+WebInspector.AnimationsSidebarPane.prototype = { |
+ /** |
+ * @param {?WebInspector.DOMNode} node |
+ */ |
+ update: function(node) |
+ { |
+ /** |
+ * @param {?Array.<!WebInspector.DOMModel.AnimationPlayer>} animationPlayers |
+ * @this {WebInspector.AnimationsSidebarPane} |
+ */ |
+ function animationPlayersCallback(animationPlayers) |
+ { |
+ this.bodyElement.removeChildren(); |
+ this._animationSections = []; |
+ if (!animationPlayers || !animationPlayers.length) { |
+ this.bodyElement.appendChild(this._emptyElement); |
+ return; |
+ } |
+ |
+ for (var i = 0; i < animationPlayers.length; ++i) { |
+ var player = animationPlayers[i]; |
+ this._animationSections[i] = new WebInspector.AnimationSection(this, player); |
+ var separatorElement = this.bodyElement.createChild("div", "sidebar-separator"); |
+ var id = player.animation().name() ? player.animation().name() : player.id(); |
+ separatorElement.createTextChild(WebInspector.UIString("Animation") + " " + id); |
+ this.bodyElement.appendChild(this._animationSections[i].element); |
+ } |
+ } |
+ |
+ if (this._selectedNode == node) { |
vsevik
2014/10/14 09:08:08
We use ===
samli
2014/10/15 08:46:44
Done.
|
+ for (var i = 0; i < this._animationSections.length; ++i) { |
vsevik
2014/10/14 09:08:09
no need to use {} for one line loops / ifs
samli
2014/10/15 08:46:44
Done.
|
+ this._animationSections[i].updateCurrentTime(); |
+ } |
+ return; |
+ } |
+ this._selectedNode = node; |
+ node.animationPlayers(animationPlayersCallback.bind(this)); |
+ }, |
+ __proto__: WebInspector.SidebarPane.prototype |
+} |
+ |
+/** |
+ * @constructor |
+ * @param {!WebInspector.AnimationsSidebarPane} parentPane |
+ * @param {?WebInspector.DOMModel.AnimationPlayer} animationPlayer |
+ */ |
+WebInspector.AnimationSection = function(parentPane, animationPlayer) |
+{ |
+ this._parentPane = parentPane; |
+ this.propertiesSection = document.createElement("div"); |
+ this._setAnimationPlayer(animationPlayer); |
+ |
+ this.element = document.createElement("div"); |
+ this.element.className = "styles-section"; |
+ |
+ this._updateThrottler = new WebInspector.Throttler(WebInspector.AnimationSection.updateTimeout); |
+ this.element.appendChild(this._createAnimationControls()); |
+ this.element.appendChild(this.propertiesSection); |
+} |
+ |
+WebInspector.AnimationSection.updateTimeout = 100; |
+ |
+WebInspector.AnimationSection.prototype = { |
+ updateCurrentTime: function() |
+ { |
+ this._updateThrottler.schedule(this._updateCurrentTime.bind(this), false); |
+ }, |
+ |
+ /** |
+ * @param {!WebInspector.Throttler.FinishCallback} finishCallback |
+ * @private |
vsevik
2014/10/14 09:08:08
we do not use @private annotations.
samli
2014/10/15 08:46:44
Done.
|
+ */ |
+ _updateCurrentTime: function(finishCallback) |
+ { |
+ /** |
+ * @param {number} currentTime |
+ * @param {boolean} isRunning |
+ * @this {WebInspector.AnimationSection} |
+ */ |
+ function updateSliderCallback(currentTime, isRunning) |
+ { |
+ this.currentTimeSlider.value = this.player.animation().iterationCount() == null ? currentTime % this.player.animation().duration() : currentTime; |
+ finishCallback(); |
+ if (isRunning && this._parentPane.isShowing()) |
+ this.updateCurrentTime(); |
+ } |
+ this.player.getCurrentState(updateSliderCallback.bind(this)); |
+ }, |
+ |
+ /** |
+ * @return {!Element} |
+ * @private |
+ */ |
+ _createCurrentTimeSlider: function() |
+ { |
+ /** |
+ * @param {!Event} e |
+ * @this {WebInspector.AnimationSection} |
+ */ |
+ function sliderInputHandler(e) |
+ { |
+ this.player.setCurrentTime(parseFloat(e.target.value), this._setAnimationPlayer.bind(this)); |
+ } |
vsevik
2014/10/14 09:08:08
Please add a blank line after a funciton
samli
2014/10/15 08:46:44
Done.
|
+ var iterationDuration = this.player.animation().duration(); |
+ var iterationCount = this.player.animation().iterationCount(); |
+ var slider = document.createElement("input"); |
+ slider.type = "range"; |
+ slider.min = 0; |
+ slider.step = 0.01; |
+ |
+ if (!iterationCount) { |
+ // Infinite iterations |
+ slider.max = iterationDuration; |
+ slider.value = this.player.currentTime() % iterationDuration; |
+ } else { |
+ slider.max = iterationCount * iterationDuration; |
+ slider.value = this.player.currentTime(); |
+ } |
+ |
+ slider.addEventListener("input", sliderInputHandler.bind(this)); |
+ this.updateCurrentTime(); |
+ return slider; |
+ }, |
+ |
+ /** |
+ * @return {!Element} |
+ * @private |
+ */ |
+ _createAnimationControls: function() |
+ { |
+ /** |
+ * @this {WebInspector.AnimationSection} |
+ */ |
+ function pauseButtonHandler() |
+ { |
+ if (this.player.paused()) { |
+ this.player.play(this._setAnimationPlayer.bind(this)); |
+ updatePauseButton.call(this, false); |
+ this.updateCurrentTime(); |
+ } else { |
+ this.player.pause(this._setAnimationPlayer.bind(this)); |
+ updatePauseButton.call(this, true); |
+ } |
+ } |
+ |
+ /** |
+ * @param {boolean} paused |
+ * @this {WebInspector.AnimationSection} |
+ */ |
+ function updatePauseButton(paused) |
+ { |
+ this._pauseButton.state = paused; |
+ if (paused) |
+ this._pauseButton.title = WebInspector.UIString("Play animation"); |
vsevik
2014/10/14 09:08:09
this._pauseButton.title = paused ? WebInspector.UI
samli
2014/10/15 08:46:44
Done.
|
+ else |
+ this._pauseButton.title = WebInspector.UIString("Pause animation"); |
+ } |
+ |
+ this._pauseButton = new WebInspector.StatusBarButton("", "animation-pause"); |
+ updatePauseButton.call(this, this.player.paused()); |
+ this._pauseButton.addEventListener("click", pauseButtonHandler, this); |
+ |
+ this.currentTimeSlider = this._createCurrentTimeSlider(); |
+ |
+ var controls = document.createElement("div"); |
+ controls.appendChild(this._pauseButton.element); |
+ controls.appendChild(this.currentTimeSlider); |
+ |
+ return controls; |
+ }, |
+ |
+ /** |
+ * @param {?WebInspector.DOMModel.AnimationPlayer} p |
+ * @private |
+ */ |
+ _setAnimationPlayer: function(p) |
+ { |
+ if (!p || p === this.player) |
+ return; |
+ this.player = p; |
+ this.propertiesSection.removeChildren(); |
+ var animationObject = { |
+ "paused": p.paused(), |
+ "finished": p.finished(), |
+ "start-time": p.startTime(), |
+ "player-playback-rate": p.playbackRate(), |
+ "id": p.id(), |
+ "start-delay": p.animation().startDelay(), |
+ "playback-rate": p.animation().playbackRate(), |
+ "iteration-start": p.animation().iterationStart(), |
+ "iteration-count": p.animation().iterationCount(), |
+ "duration": p.animation().duration(), |
+ "direction": p.animation().direction(), |
+ "fill-mode": p.animation().fillMode(), |
+ "time-fraction": p.animation().timeFraction() |
+ }; |
+ var obj = WebInspector.RemoteObject.fromLocalObject(animationObject); |
+ var section = new WebInspector.ObjectPropertiesSection(obj, WebInspector.UIString("Animation Properties")); |
+ this.propertiesSection.appendChild(section.element); |
+ } |
+} |