зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1120852 - 2 - Don't start the animation timeline UI before the animation delay has passed; r=bgrins
This commit is contained in:
Родитель
9e893ce9f0
Коммит
14d84f5620
|
@ -193,21 +193,26 @@ PlayerWidget.prototype = {
|
|||
});
|
||||
let titleHTML = "";
|
||||
|
||||
// Name
|
||||
// Name.
|
||||
if (state.name) {
|
||||
// Css animations have names
|
||||
// Css animations have names.
|
||||
titleHTML += L10N.getStr("player.animationNameLabel");
|
||||
titleHTML += "<strong>" + state.name + "</strong>";
|
||||
} else {
|
||||
// Css transitions don't
|
||||
// Css transitions don't.
|
||||
titleHTML += L10N.getStr("player.transitionNameLabel");
|
||||
}
|
||||
|
||||
// Duration and iteration count
|
||||
// Duration, delay and iteration count.
|
||||
titleHTML += "<span class='meta-data'>";
|
||||
titleHTML += L10N.getStr("player.animationDurationLabel");
|
||||
titleHTML += "<strong>" + L10N.getFormatStr("player.timeLabel",
|
||||
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");
|
||||
let count = state.iterationCount || L10N.getStr("player.infiniteIterationCount");
|
||||
titleHTML += "<strong>" + count + "</strong>";
|
||||
|
@ -215,7 +220,7 @@ PlayerWidget.prototype = {
|
|||
|
||||
titleEl.innerHTML = titleHTML;
|
||||
|
||||
// Timeline widget
|
||||
// Timeline widget.
|
||||
let timelineEl = createNode({
|
||||
parent: this.el,
|
||||
attributes: {
|
||||
|
@ -223,7 +228,7 @@ PlayerWidget.prototype = {
|
|||
}
|
||||
});
|
||||
|
||||
// Playback control buttons container
|
||||
// Playback control buttons container.
|
||||
let playbackControlsEl = createNode({
|
||||
parent: timelineEl,
|
||||
attributes: {
|
||||
|
@ -241,7 +246,7 @@ PlayerWidget.prototype = {
|
|||
}
|
||||
});
|
||||
|
||||
// Sliders container
|
||||
// Sliders container.
|
||||
let slidersContainerEl = createNode({
|
||||
parent: timelineEl,
|
||||
attributes: {
|
||||
|
@ -249,9 +254,9 @@ PlayerWidget.prototype = {
|
|||
}
|
||||
});
|
||||
|
||||
let max = state.duration; // Infinite iterations
|
||||
let max = state.duration; // Infinite iterations.
|
||||
if (state.iterationCount) {
|
||||
// Finite iterations
|
||||
// Finite iterations.
|
||||
max = state.iterationCount * state.duration;
|
||||
}
|
||||
|
||||
|
@ -267,6 +272,7 @@ PlayerWidget.prototype = {
|
|||
"min": "0",
|
||||
"max": max,
|
||||
"step": "10",
|
||||
"value": "0",
|
||||
// The currentTime isn't settable yet, so disable the timeline slider
|
||||
"disabled": "true"
|
||||
}
|
||||
|
@ -280,7 +286,7 @@ PlayerWidget.prototype = {
|
|||
}
|
||||
});
|
||||
this.timeDisplayEl.textContent = L10N.getFormatStr("player.timeLabel",
|
||||
this.getFormattedTime());
|
||||
this.getFormattedTime(0));
|
||||
|
||||
this.containerEl.appendChild(this.el);
|
||||
},
|
||||
|
@ -290,14 +296,11 @@ PlayerWidget.prototype = {
|
|||
* @param {Number} time Defaults to the player's currentTime.
|
||||
* @return {String} The formatted time, e.g. "10.55"
|
||||
*/
|
||||
getFormattedTime: function(time=this.player.state.currentTime) {
|
||||
let str = time/1000 + "";
|
||||
str = str.split(".");
|
||||
if (str.length === 1) {
|
||||
return str[0] + ".00";
|
||||
} else {
|
||||
return str[0] + "." + str[1].substring(0, 2);
|
||||
}
|
||||
getFormattedTime: function(time) {
|
||||
return (time/1000).toLocaleString(undefined, {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -390,6 +393,12 @@ PlayerWidget.prototype = {
|
|||
displayTime: function(time) {
|
||||
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.getFormattedTime(time));
|
||||
if (!state.iterationCount && time !== state.duration) {
|
||||
|
|
|
@ -11,8 +11,10 @@ support-files =
|
|||
[browser_animation_play_pause_button.js]
|
||||
[browser_animation_playerFronts_are_refreshed.js]
|
||||
[browser_animation_playerWidgets_destroy.js]
|
||||
[browser_animation_playerWidgets_meta_data.js]
|
||||
[browser_animation_refresh_when_active.js]
|
||||
[browser_animation_same_nb_of_playerWidgets_and_playerFronts.js]
|
||||
[browser_animation_shows_player_on_valid_node.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]
|
|
@ -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");
|
||||
});
|
|
@ -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");
|
||||
});
|
|
@ -4,8 +4,8 @@
|
|||
<meta charset="UTF-8">
|
||||
<style>
|
||||
.ball {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
background: #f06;
|
||||
|
||||
|
@ -13,25 +13,33 @@
|
|||
}
|
||||
|
||||
.still {
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
top: 0;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.animated {
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
top: 100px;
|
||||
left: 10px;
|
||||
|
||||
animation: simple-animation 2s infinite alternate;
|
||||
}
|
||||
|
||||
.multi {
|
||||
top: 100px;
|
||||
left: 400px;
|
||||
top: 200px;
|
||||
left: 10px;
|
||||
|
||||
animation: simple-animation 2s infinite alternate,
|
||||
other-animation 5s infinite alternate;
|
||||
}
|
||||
|
||||
.delayed {
|
||||
top: 300px;
|
||||
left: 10px;
|
||||
background: rebeccapurple;
|
||||
|
||||
animation: simple-animation 3s 60s 10;
|
||||
}
|
||||
|
||||
@keyframes simple-animation {
|
||||
100% {
|
||||
transform: translateX(300px);
|
||||
|
@ -50,5 +58,6 @@
|
|||
<div class="ball still"></div>
|
||||
<div class="ball animated"></div>
|
||||
<div class="ball multi"></div>
|
||||
<div class="ball delayed"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -26,6 +26,11 @@ player.transitionNameLabel=Transition
|
|||
# displayed before the animation 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):
|
||||
# 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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче