Bug 1120852 - 2 - Don't start the animation timeline UI before the animation delay has passed; r=bgrins

This commit is contained in:
Patrick Brosset 2015-01-15 10:40:55 +01:00
parent 9b1ad3b095
commit aacd37d7d8
6 changed files with 125 additions and 27 deletions

View File

@ -193,21 +193,26 @@ PlayerWidget.prototype = {
}); });
let titleHTML = ""; let titleHTML = "";
// Name // Name.
if (state.name) { if (state.name) {
// Css animations have names // Css animations have names.
titleHTML += L10N.getStr("player.animationNameLabel"); titleHTML += L10N.getStr("player.animationNameLabel");
titleHTML += "<strong>" + state.name + "</strong>"; titleHTML += "<strong>" + state.name + "</strong>";
} else { } else {
// Css transitions don't // Css transitions don't.
titleHTML += L10N.getStr("player.transitionNameLabel"); titleHTML += L10N.getStr("player.transitionNameLabel");
} }
// Duration and iteration count // Duration, delay and iteration count.
titleHTML += "<span class='meta-data'>"; titleHTML += "<span class='meta-data'>";
titleHTML += L10N.getStr("player.animationDurationLabel"); titleHTML += L10N.getStr("player.animationDurationLabel");
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel", titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
this.getFormattedTime(state.duration)) + "</strong>"; this.getFormattedTime(state.duration)) + "</strong>";
if (state.delay) {
titleHTML += L10N.getStr("player.animationDelayLabel");
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
this.getFormattedTime(state.delay)) + "</strong>";
}
titleHTML += L10N.getStr("player.animationIterationCountLabel"); titleHTML += L10N.getStr("player.animationIterationCountLabel");
let count = state.iterationCount || L10N.getStr("player.infiniteIterationCount"); let count = state.iterationCount || L10N.getStr("player.infiniteIterationCount");
titleHTML += "<strong>" + count + "</strong>"; titleHTML += "<strong>" + count + "</strong>";
@ -215,7 +220,7 @@ PlayerWidget.prototype = {
titleEl.innerHTML = titleHTML; titleEl.innerHTML = titleHTML;
// Timeline widget // Timeline widget.
let timelineEl = createNode({ let timelineEl = createNode({
parent: this.el, parent: this.el,
attributes: { attributes: {
@ -223,7 +228,7 @@ PlayerWidget.prototype = {
} }
}); });
// Playback control buttons container // Playback control buttons container.
let playbackControlsEl = createNode({ let playbackControlsEl = createNode({
parent: timelineEl, parent: timelineEl,
attributes: { attributes: {
@ -241,7 +246,7 @@ PlayerWidget.prototype = {
} }
}); });
// Sliders container // Sliders container.
let slidersContainerEl = createNode({ let slidersContainerEl = createNode({
parent: timelineEl, parent: timelineEl,
attributes: { attributes: {
@ -249,9 +254,9 @@ PlayerWidget.prototype = {
} }
}); });
let max = state.duration; // Infinite iterations let max = state.duration; // Infinite iterations.
if (state.iterationCount) { if (state.iterationCount) {
// Finite iterations // Finite iterations.
max = state.iterationCount * state.duration; max = state.iterationCount * state.duration;
} }
@ -267,6 +272,7 @@ PlayerWidget.prototype = {
"min": "0", "min": "0",
"max": max, "max": max,
"step": "10", "step": "10",
"value": "0",
// The currentTime isn't settable yet, so disable the timeline slider // The currentTime isn't settable yet, so disable the timeline slider
"disabled": "true" "disabled": "true"
} }
@ -280,7 +286,7 @@ PlayerWidget.prototype = {
} }
}); });
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel", this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
this.getFormattedTime()); this.getFormattedTime(0));
this.containerEl.appendChild(this.el); this.containerEl.appendChild(this.el);
}, },
@ -290,14 +296,11 @@ PlayerWidget.prototype = {
* @param {Number} time Defaults to the player's currentTime. * @param {Number} time Defaults to the player's currentTime.
* @return {String} The formatted time, e.g. "10.55" * @return {String} The formatted time, e.g. "10.55"
*/ */
getFormattedTime: function(time=this.player.state.currentTime) { getFormattedTime: function(time) {
let str = time/1000 + ""; return (time/1000).toLocaleString(undefined, {
str = str.split("."); minimumFractionDigits: 2,
if (str.length === 1) { maximumFractionDigits: 2
return str[0] + ".00"; });
} else {
return str[0] + "." + str[1].substring(0, 2);
}
}, },
/** /**
@ -390,6 +393,12 @@ PlayerWidget.prototype = {
displayTime: function(time) { displayTime: function(time) {
let state = this.player.state; let state = this.player.state;
// If the animation is delayed, don't start displaying the time until the
// delay has passed.
if (state.delay) {
time = Math.max(0, time - state.delay);
}
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel", this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
this.getFormattedTime(time)); this.getFormattedTime(time));
if (!state.iterationCount && time !== state.duration) { if (!state.iterationCount && time !== state.duration) {

View File

@ -11,8 +11,10 @@ support-files =
[browser_animation_play_pause_button.js] [browser_animation_play_pause_button.js]
[browser_animation_playerFronts_are_refreshed.js] [browser_animation_playerFronts_are_refreshed.js]
[browser_animation_playerWidgets_destroy.js] [browser_animation_playerWidgets_destroy.js]
[browser_animation_playerWidgets_meta_data.js]
[browser_animation_refresh_when_active.js] [browser_animation_refresh_when_active.js]
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js] [browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
[browser_animation_shows_player_on_valid_node.js] [browser_animation_shows_player_on_valid_node.js]
[browser_animation_timeline_animates.js] [browser_animation_timeline_animates.js]
[browser_animation_ui_updates_when_animation_changes.js] [browser_animation_timeline_waits_for_delay.js]
[browser_animation_ui_updates_when_animation_changes.js]

View File

@ -0,0 +1,49 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that player widgets show the right player meta-data (name, duration,
// iteration count, delay).
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the simple animated node");
yield selectNode(".animated", inspector);
let titleEl = panel.playerWidgets[0].el.querySelector(".animation-title");
ok(titleEl,
"The player widget has a title element, where meta-data should be displayed");
let nameEl = titleEl.querySelector("strong");
ok(nameEl, "The first <strong> tag was retrieved, it should contain the name");
is(nameEl.textContent, "simple-animation", "The animation name is correct");
let metaDataEl = titleEl.querySelector(".meta-data");
ok(metaDataEl, "The meta-data element exists");
let metaDataEls = metaDataEl.querySelectorAll("strong");
is(metaDataEls.length, 2, "2 meta-data elements were found");
is(metaDataEls[0].textContent, "2.00s",
"The first meta-data is the duration, and is correct");
info("Select the node with the delayed animation");
yield selectNode(".delayed", inspector);
titleEl = panel.playerWidgets[0].el.querySelector(".animation-title");
nameEl = titleEl.querySelector("strong");
is(nameEl.textContent, "simple-animation", "The animation name is correct");
metaDataEls = titleEl.querySelectorAll(".meta-data strong");
is(metaDataEls.length, 3,
"3 meta-data elements were found for the delayed animation");
is(metaDataEls[0].textContent, "3.00s",
"The first meta-data is the duration, and is correct");
is(metaDataEls[1].textContent, "60.00s",
"The second meta-data is the delay, and is correct");
is(metaDataEls[2].textContent, "10",
"The third meta-data is the iteration count, and is correct");
});

View File

@ -0,0 +1,24 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the currentTime timeline doesn't move if the animation is currently
// waiting for an animation-delay.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the delayed animation node");
yield selectNode(".delayed", inspector);
let widget = panel.playerWidgets[0];
let timeline = widget.currentTimeEl;
is(timeline.value, 0, "The timeline is at 0 since the animation hasn't started");
let timeLabel = widget.timeDisplayEl;
is(timeLabel.textContent, "0.00s", "The current time is 0");
});

View File

@ -4,8 +4,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<style> <style>
.ball { .ball {
width: 100px; width: 80px;
height: 100px; height: 80px;
border-radius: 50%; border-radius: 50%;
background: #f06; background: #f06;
@ -13,25 +13,33 @@
} }
.still { .still {
top: 50px; top: 0;
left: 50px; left: 10px;
} }
.animated { .animated {
top: 200px; top: 100px;
left: 200px; left: 10px;
animation: simple-animation 2s infinite alternate; animation: simple-animation 2s infinite alternate;
} }
.multi { .multi {
top: 100px; top: 200px;
left: 400px; left: 10px;
animation: simple-animation 2s infinite alternate, animation: simple-animation 2s infinite alternate,
other-animation 5s infinite alternate; other-animation 5s infinite alternate;
} }
.delayed {
top: 300px;
left: 10px;
background: rebeccapurple;
animation: simple-animation 3s 60s 10;
}
@keyframes simple-animation { @keyframes simple-animation {
100% { 100% {
transform: translateX(300px); transform: translateX(300px);
@ -50,5 +58,6 @@
<div class="ball still"></div> <div class="ball still"></div>
<div class="ball animated"></div> <div class="ball animated"></div>
<div class="ball multi"></div> <div class="ball multi"></div>
<div class="ball delayed"></div>
</body> </body>
</html> </html>

View File

@ -26,6 +26,11 @@ player.transitionNameLabel=Transition
# displayed before the animation duration. # displayed before the animation duration.
player.animationDurationLabel=Duration: player.animationDurationLabel=Duration:
# LOCALIZATION NOTE (player.animationDelayLabel):
# This string is displayed in each animation player widget. It is the label
# displayed before the animation delay.
player.animationDelayLabel=Delay:
# LOCALIZATION NOTE (player.animationIterationCountLabel): # LOCALIZATION NOTE (player.animationIterationCountLabel):
# This string is displayed in each animation player widget. It is the label # This string is displayed in each animation player widget. It is the label
# displayed before the number of times the animation is set to repeat. # displayed before the number of times the animation is set to repeat.