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

Side by Side Diff: Source/devtools/front_end/elements/AnimationTimeline.js

Issue 967213002: Devtools Animations: Represent delay and end-delay on the animation timeline (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Add test Created 5 years, 9 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 * @param {!WebInspector.StylesSidebarPane} stylesPane 8 * @param {!WebInspector.StylesSidebarPane} stylesPane
9 */ 9 */
10 WebInspector.AnimationTimeline = function(stylesPane) 10 WebInspector.AnimationTimeline = function(stylesPane)
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 /** 270 /**
271 * @param {!WebInspector.AnimationModel.AnimationPlayer} animation 271 * @param {!WebInspector.AnimationModel.AnimationPlayer} animation
272 * @return {boolean} 272 * @return {boolean}
273 */ 273 */
274 _resizeWindow: function(animation) 274 _resizeWindow: function(animation)
275 { 275 {
276 var resized = false; 276 var resized = false;
277 if (!this._startTime) 277 if (!this._startTime)
278 this._startTime = animation.startTime(); 278 this._startTime = animation.startTime();
279 279
280 // This shows at most 2 iterations 280 // This shows at most 3 iterations
281 var iterations = animation.source().iterations() || 1; 281 var duration = animation.source().duration() * Math.min(3, animation.sou rce().iterations());
282 var duration = animation.source().duration() * Math.min(3, iterations); 282 var requiredDuration = animation.startTime() + animation.source().delay( ) + duration + animation.source().endDelay() - this.startTime();
283 var requiredDuration = animation.startTime() + duration + animation.sour ce().delay() - this.startTime();
284 if (requiredDuration > this._duration * 0.8) { 283 if (requiredDuration > this._duration * 0.8) {
285 resized = true; 284 resized = true;
286 this._duration = requiredDuration * 1.5; 285 this._duration = requiredDuration * 1.5;
287 this._animateTime(animation.startTime() - this.startTime()); 286 this._animateTime(animation.startTime() - this.startTime());
288 } 287 }
289 return resized; 288 return resized;
290 }, 289 },
291 290
292 /** 291 /**
293 * @param {number=} time 292 * @param {number=} time
294 */ 293 */
295 _animateTime: function(time) 294 _animateTime: function(time)
296 { 295 {
297 var oldPlayer = this._scrubberPlayer; 296 var oldPlayer = this._scrubberPlayer;
298 297
299 this._scrubberPlayer = this._timelineScrubber.animate([ 298 this._scrubberPlayer = this._timelineScrubber.animate([
300 { transform: "translateX(0px)" }, 299 { transform: "translateX(0px)" },
301 { transform: "translateX(" + (this._cachedTimelineWidth - this._scr ubberRadius) + "px)" } 300 { transform: "translateX(" + (this.width() - this._scrubberRadius) + "px)" }
302 ], { duration: this.duration() - this._scrubberRadius / this.pixelMsRati o(), fill: "forwards" }); 301 ], { duration: this.duration() - this._scrubberRadius / this.pixelMsRati o(), fill: "forwards" });
303 this._scrubberPlayer.playbackRate = this._animationsPlaybackRate; 302 this._scrubberPlayer.playbackRate = this._animationsPlaybackRate;
304 303
305 if (time !== undefined) 304 if (time !== undefined)
306 this._scrubberPlayer.currentTime = time; 305 this._scrubberPlayer.currentTime = time;
307 else if (oldPlayer.playState === "finished") 306 else if (oldPlayer.playState === "finished")
308 this._scrubberPlayer.finish(); 307 this._scrubberPlayer.finish();
309 else 308 else
310 this._scrubberPlayer.startTime = oldPlayer.startTime; 309 this._scrubberPlayer.startTime = oldPlayer.startTime;
311 310
312 if (oldPlayer) 311 if (oldPlayer)
313 oldPlayer.cancel(); 312 oldPlayer.cancel();
314 this._timelineScrubber.classList.remove("animation-timeline-end"); 313 this._timelineScrubber.classList.remove("animation-timeline-end");
315 this._timelineScrubberHead.window().requestAnimationFrame(this._updateSc rubber.bind(this)); 314 this._timelineScrubberHead.window().requestAnimationFrame(this._updateSc rubber.bind(this));
316 }, 315 },
317 316
318 /** 317 /**
319 * @return {number} 318 * @return {number}
320 */ 319 */
321 pixelMsRatio: function() 320 pixelMsRatio: function()
322 { 321 {
323 return this._cachedTimelineWidth / this.duration() || 0; 322 return this.width() / this.duration() || 0;
324 }, 323 },
325 324
326 /** 325 /**
327 * @param {number} timestamp 326 * @param {number} timestamp
328 */ 327 */
329 _updateScrubber: function(timestamp) 328 _updateScrubber: function(timestamp)
330 { 329 {
331 this._timelineScrubberHead.textContent = WebInspector.UIString(Number.mi llisToString(this._scrubberPlayer.currentTime)); 330 this._timelineScrubberHead.textContent = WebInspector.UIString(Number.mi llisToString(this._scrubberPlayer.currentTime));
332 if (this._scrubberPlayer.playState === "pending" || this._scrubberPlayer .playState === "running") { 331 if (this._scrubberPlayer.playState === "pending" || this._scrubberPlayer .playState === "running") {
333 this._timelineScrubberHead.window().requestAnimationFrame(this._upda teScrubber.bind(this)); 332 this._timelineScrubberHead.window().requestAnimationFrame(this._upda teScrubber.bind(this));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 __proto__: WebInspector.VBox.prototype 386 __proto__: WebInspector.VBox.prototype
388 } 387 }
389 388
390 /** 389 /**
391 * @constructor 390 * @constructor
392 * @param {!WebInspector.AnimationModel.AnimationNode} animationNode 391 * @param {!WebInspector.AnimationModel.AnimationNode} animationNode
393 */ 392 */
394 WebInspector.AnimationTimeline.NodeUI = function(animationNode) { 393 WebInspector.AnimationTimeline.NodeUI = function(animationNode) {
395 /** 394 /**
396 * @param {?WebInspector.DOMNode} node 395 * @param {?WebInspector.DOMNode} node
396 * @this {WebInspector.AnimationTimeline.NodeUI}
397 */ 397 */
398 function nodeResolved(node) 398 function nodeResolved(node)
399 { 399 {
400 description.appendChild(WebInspector.DOMPresentationUtils.linkifyNodeRef erence(node)); 400 this._description.appendChild(WebInspector.DOMPresentationUtils.linkifyN odeReference(node));
401 } 401 }
402 402
403 this._rows = []; 403 this._rows = [];
404 this.element = createElementWithClass("div", "animation-node-row"); 404 this.element = createElementWithClass("div", "animation-node-row");
405 var description = this.element.createChild("div", "animation-node-descriptio n"); 405 this._description = this.element.createChild("div", "animation-node-descript ion");
406 animationNode.getNode(nodeResolved); 406 animationNode.getNode(nodeResolved.bind(this));
407 this._timelineElement = this.element.createChild("div", "animation-node-time line"); 407 this._timelineElement = this.element.createChild("div", "animation-node-time line");
408 } 408 }
409 409
410 /** @typedef {{element: !Element, animations: !Array<!WebInspector.AnimationUI>} } */ 410 /** @typedef {{element: !Element, animations: !Array<!WebInspector.AnimationUI>} } */
411 WebInspector.AnimationTimeline.NodeRow; 411 WebInspector.AnimationTimeline.NodeRow;
412 412
413 WebInspector.AnimationTimeline.NodeUI.prototype = { 413 WebInspector.AnimationTimeline.NodeUI.prototype = {
414 /** 414 /**
415 * @param {!WebInspector.AnimationModel.AnimationPlayer} animation 415 * @param {!WebInspector.AnimationModel.AnimationPlayer} animation
416 * @return {!WebInspector.AnimationTimeline.NodeRow} 416 * @return {!WebInspector.AnimationTimeline.NodeRow}
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 if (this._animation.source().keyframesRule()) 477 if (this._animation.source().keyframesRule())
478 this._keyframes = this._animation.source().keyframesRule().keyframes(); 478 this._keyframes = this._animation.source().keyframesRule().keyframes();
479 479
480 this._nameElement = parentElement.createChild("div", "animation-name"); 480 this._nameElement = parentElement.createChild("div", "animation-name");
481 this._nameElement.textContent = this._animation.name(); 481 this._nameElement.textContent = this._animation.name();
482 482
483 this._svg = parentElement.createSVGChild("svg", "animation-ui"); 483 this._svg = parentElement.createSVGChild("svg", "animation-ui");
484 this._svg.setAttribute("height", WebInspector.AnimationUI.Options.AnimationS VGHeight); 484 this._svg.setAttribute("height", WebInspector.AnimationUI.Options.AnimationS VGHeight);
485 this._svg.style.marginLeft = "-" + WebInspector.AnimationUI.Options.Animatio nMargin + "px"; 485 this._svg.style.marginLeft = "-" + WebInspector.AnimationUI.Options.Animatio nMargin + "px";
486 this._svg.addEventListener("mousedown", this._mouseDown.bind(this, WebInspec tor.AnimationUI.MouseEvents.AnimationDrag, null)); 486 this._svg.addEventListener("mousedown", this._mouseDown.bind(this, WebInspec tor.AnimationUI.MouseEvents.AnimationDrag, null));
487 this._activeIntervalGroup = this._svg.createSVGChild("g");
487 488
488 /** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints : !Object.<number, !Element>, beziers: !Object.<number, !Element>}>} */ 489 /** @type {!Array.<{group: ?Element, animationLine: ?Element, keyframePoints : !Object.<number, !Element>, beziers: !Object.<number, !Element>}>} */
489 this._cachedElements = []; 490 this._cachedElements = [];
490 491
491 this._movementInMs = 0; 492 this._movementInMs = 0;
492 this.redraw(); 493 this.redraw();
493 } 494 }
494 495
495 /** 496 /**
496 * @enum {string} 497 * @enum {string}
(...skipping 16 matching lines...) Expand all
513 514
514 /** 515 /**
515 * @param {?WebInspector.DOMNode} node 516 * @param {?WebInspector.DOMNode} node
516 */ 517 */
517 setNode: function(node) 518 setNode: function(node)
518 { 519 {
519 this._node = node; 520 this._node = node;
520 }, 521 },
521 522
522 /** 523 /**
524 * @param {!Element} parentElement
525 * @param {string} className
526 */
527 _createLine: function(parentElement, className)
528 {
529 var line = parentElement.createSVGChild("line", className);
530 line.setAttribute("x1", WebInspector.AnimationUI.Options.AnimationMargin );
531 line.setAttribute("y1", WebInspector.AnimationUI.Options.AnimationHeight );
532 line.setAttribute("y2", WebInspector.AnimationUI.Options.AnimationHeight );
533 line.style.stroke = this._color();
534 return line;
535 },
536
537 /**
523 * @param {number} iteration 538 * @param {number} iteration
524 * @param {!Element} parentElement 539 * @param {!Element} parentElement
525 */ 540 */
526 _drawAnimationLine: function(iteration, parentElement) 541 _drawAnimationLine: function(iteration, parentElement)
527 { 542 {
528 var cache = this._cachedElements[iteration]; 543 var cache = this._cachedElements[iteration];
529 if (!cache.animationLine) 544 if (!cache.animationLine)
530 cache.animationLine = parentElement.createSVGChild("line", "animatio n-line"); 545 cache.animationLine = this._createLine(parentElement, "animation-lin e");
531 cache.animationLine.setAttribute("y1", WebInspector.AnimationUI.Options. AnimationHeight);
532 cache.animationLine.setAttribute("x1", WebInspector.AnimationUI.Options. AnimationMargin);
533 cache.animationLine.setAttribute("x2", this._duration() * this._timeline .pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin); 546 cache.animationLine.setAttribute("x2", this._duration() * this._timeline .pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin);
534 cache.animationLine.setAttribute("y2", WebInspector.AnimationUI.Options. AnimationHeight);
535 cache.animationLine.style.stroke = this._color();
536 }, 547 },
537 548
538 /** 549 /**
550 * @param {!Element} parentElement
551 */
552 _drawDelayLine: function(parentElement)
553 {
554 if (!this._delayLine) {
555 this._delayLine = this._createLine(parentElement, "animation-delay-l ine");
556 this._endDelayLine = this._createLine(parentElement, "animation-dela y-line");
557 }
558 this._delayLine.setAttribute("x1", WebInspector.AnimationUI.Options.Anim ationMargin);
559 this._delayLine.setAttribute("x2", this._delay() * this._timeline.pixelM sRatio() + WebInspector.AnimationUI.Options.AnimationMargin);
560 var leftMargin = (this._delay() + this._duration() * this._animation.sou rce().iterations()) * this._timeline.pixelMsRatio();
561 this._endDelayLine.style.transform = "translateX(" + Math.min(leftMargin , this._timeline.width()) + "px)";
562 this._endDelayLine.setAttribute("x1", WebInspector.AnimationUI.Options.A nimationMargin);
563 this._endDelayLine.setAttribute("x2", this._animation.source().endDelay( ) * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMa rgin);
564 },
565
566 /**
539 * @param {number} iteration 567 * @param {number} iteration
540 * @param {!Element} parentElement 568 * @param {!Element} parentElement
541 * @param {number} x 569 * @param {number} x
542 * @param {number} keyframeIndex 570 * @param {number} keyframeIndex
543 * @param {boolean} attachEvents 571 * @param {boolean} attachEvents
544 */ 572 */
545 _drawPoint: function(iteration, parentElement, x, keyframeIndex, attachEvent s) 573 _drawPoint: function(iteration, parentElement, x, keyframeIndex, attachEvent s)
546 { 574 {
547 if (this._cachedElements[iteration].keyframePoints[keyframeIndex]) { 575 if (this._cachedElements[iteration].keyframePoints[keyframeIndex]) {
548 this._cachedElements[iteration].keyframePoints[keyframeIndex].setAtt ribute("cx", x); 576 this._cachedElements[iteration].keyframePoints[keyframeIndex].setAtt ribute("cx", x);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 var bezierCache = this._cachedElements[iteration].beziers; 613 var bezierCache = this._cachedElements[iteration].beziers;
586 if (!bezierCache[keyframeIndex]) 614 if (!bezierCache[keyframeIndex])
587 bezierCache[keyframeIndex] = parentElement.createSVGChild("path", "a nimation-keyframe"); 615 bezierCache[keyframeIndex] = parentElement.createSVGChild("path", "a nimation-keyframe");
588 bezierCache[keyframeIndex].style.transform = "translateX(" + leftDistanc e + "px)"; 616 bezierCache[keyframeIndex].style.transform = "translateX(" + leftDistanc e + "px)";
589 bezierCache[keyframeIndex].style.fill = this._color(); 617 bezierCache[keyframeIndex].style.fill = this._color();
590 WebInspector.BezierUI.drawVelocityChart(bezier, bezierCache[keyframeInde x], width); 618 WebInspector.BezierUI.drawVelocityChart(bezier, bezierCache[keyframeInde x], width);
591 }, 619 },
592 620
593 redraw: function() 621 redraw: function()
594 { 622 {
595 var iterationWidth = this._duration() * this._timeline.pixelMsRatio(); 623 var durationWithDelay = this._delay() + this._duration() * this._animati on.source().iterations() + this._animation.source().endDelay();
596 var svgWidth = this._animation.source().iterations() ? Math.min(this._ti meline.width(), iterationWidth * this._animation.source().iterations()) : this._ timeline.width(); 624 var svgWidth = Math.min(this._timeline.width(), durationWithDelay * this ._timeline.pixelMsRatio());
597 svgWidth += 2 * WebInspector.AnimationUI.Options.AnimationMargin; 625 var leftMargin = (this._animation.startTime() - this._timeline.startTime ()) * this._timeline.pixelMsRatio();
598 var leftMargin = (this._animation.startTime() - this._timeline.startTime () + this._delay()) * this._timeline.pixelMsRatio(); 626
599 this._svg.setAttribute("width", svgWidth); 627 this._svg.setAttribute("width", svgWidth + 2 * WebInspector.AnimationUI. Options.AnimationMargin);
600 this._svg.style.transform = "translateX(" + leftMargin + "px)"; 628 this._svg.style.transform = "translateX(" + leftMargin + "px)";
601 this._nameElement.style.transform = "translateX(" + leftMargin + "px)"; 629 this._activeIntervalGroup.style.transform = "translateX(" + (this._delay () * this._timeline.pixelMsRatio()) + "px)";
602 this._nameElement.style.width = svgWidth + "px"; 630
631 this._nameElement.style.transform = "translateX(" + (leftMargin + this._ delay() * this._timeline.pixelMsRatio() + WebInspector.AnimationUI.Options.Anima tionMargin) + "px)";
632 this._nameElement.style.width = this._duration() * this._timeline.pixelM sRatio() + "px";
633 this._drawDelayLine(this._svg);
603 634
604 if (this._animation.type() === "CSSTransition") { 635 if (this._animation.type() === "CSSTransition") {
605 this._renderTransition(); 636 this._renderTransition();
606 return; 637 return;
607 } 638 }
608 639
609 var numIterations = this._animation.source().iterations() ? this._animat ion.source().iterations() : Infinity; 640 this._renderIteration(this._activeIntervalGroup, 0);
610 this._renderIteration(this._svg, 0);
611 if (!this._tailGroup) 641 if (!this._tailGroup)
612 this._tailGroup = this._svg.createSVGChild("g", "animation-tail-iter ations"); 642 this._tailGroup = this._activeIntervalGroup.createSVGChild("g", "ani mation-tail-iterations");
613 for (var iteration = 1; iteration < numIterations && iterationWidth * (i teration - 1) < this._timeline.width(); iteration++) 643 var iterationWidth = this._duration() * this._timeline.pixelMsRatio();
644 for (var iteration = 1; iteration < this._animation.source().iterations( ) && iterationWidth * (iteration - 1) < this._timeline.width(); iteration++)
614 this._renderIteration(this._tailGroup, iteration); 645 this._renderIteration(this._tailGroup, iteration);
615 }, 646 },
616 647
617 _renderTransition: function() 648 _renderTransition: function()
618 { 649 {
619 if (!this._cachedElements[0]) 650 if (!this._cachedElements[0])
620 this._cachedElements[0] = { animationLine: null, keyframePoints: {}, beziers: {}, group: null }; 651 this._cachedElements[0] = { animationLine: null, keyframePoints: {}, beziers: {}, group: null };
621 this._drawAnimationLine(0, this._svg); 652 this._drawAnimationLine(0, this._activeIntervalGroup);
622 var bezier = WebInspector.Geometry.CubicBezier.parse(this._animation.sou rce().easing()); 653 var bezier = WebInspector.Geometry.CubicBezier.parse(this._animation.sou rce().easing());
623 // FIXME: add support for step functions 654 // FIXME: add support for step functions
624 if (bezier) 655 if (bezier)
625 this._renderBezierKeyframe(0, 0, this._svg, WebInspector.AnimationUI .Options.AnimationMargin, this._duration() * this._timeline.pixelMsRatio(), bezi er); 656 this._renderBezierKeyframe(0, 0, this._activeIntervalGroup, WebInspe ctor.AnimationUI.Options.AnimationMargin, this._duration() * this._timeline.pixe lMsRatio(), bezier);
626 this._drawPoint(0, this._svg, WebInspector.AnimationUI.Options.Animation Margin, 0, true); 657 this._drawPoint(0, this._activeIntervalGroup, WebInspector.AnimationUI.O ptions.AnimationMargin, 0, true);
627 this._drawPoint(0, this._svg, this._duration() * this._timeline.pixelMsR atio() + WebInspector.AnimationUI.Options.AnimationMargin, -1, true); 658 this._drawPoint(0, this._activeIntervalGroup, this._duration() * this._t imeline.pixelMsRatio() + WebInspector.AnimationUI.Options.AnimationMargin, -1, t rue);
628 }, 659 },
629 660
630 /** 661 /**
631 * @param {!Element} parentElement 662 * @param {!Element} parentElement
632 * @param {number} iteration 663 * @param {number} iteration
633 */ 664 */
634 _renderIteration: function(parentElement, iteration) 665 _renderIteration: function(parentElement, iteration)
635 { 666 {
636 if (!this._cachedElements[iteration]) 667 if (!this._cachedElements[iteration])
637 this._cachedElements[iteration] = { animationLine: null, keyframePoi nts: {}, beziers: {}, group: parentElement.createSVGChild("g") }; 668 this._cachedElements[iteration] = { animationLine: null, keyframePoi nts: {}, beziers: {}, group: parentElement.createSVGChild("g") };
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 "Light Blue": WebInspector.Color.parse("#03A9F4"), 873 "Light Blue": WebInspector.Color.parse("#03A9F4"),
843 "Deep Orange": WebInspector.Color.parse("#FF5722"), 874 "Deep Orange": WebInspector.Color.parse("#FF5722"),
844 "Blue": WebInspector.Color.parse("#5677FC"), 875 "Blue": WebInspector.Color.parse("#5677FC"),
845 "Lime": WebInspector.Color.parse("#CDDC39"), 876 "Lime": WebInspector.Color.parse("#CDDC39"),
846 "Blue Grey": WebInspector.Color.parse("#607D8B"), 877 "Blue Grey": WebInspector.Color.parse("#607D8B"),
847 "Pink": WebInspector.Color.parse("#E91E63"), 878 "Pink": WebInspector.Color.parse("#E91E63"),
848 "Green": WebInspector.Color.parse("#0F9D58"), 879 "Green": WebInspector.Color.parse("#0F9D58"),
849 "Brown": WebInspector.Color.parse("#795548"), 880 "Brown": WebInspector.Color.parse("#795548"),
850 "Cyan": WebInspector.Color.parse("#00BCD4") 881 "Cyan": WebInspector.Color.parse("#00BCD4")
851 } 882 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698