Javascript 动画倒计时
Javascript animated countdown
我一直在尝试创建一个倒计时,每次计数器更改时都会为文本设置动画。我可以在开始时执行更改,但不确定如何清除更改并重复。
HTML & CSS
<!DOCTYPE html>
<html>
<head>
<!--meta http-equiv="refresh" content="4; url=index.php"-->
<style type="text/css">
p
{
transition: 1s;
font-size: 100%;
}
</style>
</head>
<body>
<p>A script on this page starts this clock:</p>
<p id="demo">Login in....</p>
<script>
//various javascript here
</script>
</body>
</html>
此脚本会在第一次计数时更改 CSS 一次,但不会在计数 2 或 1 时更改。
//Set the counter variable
var counter= 4;
//Set the timer to count the counter down
var timer = setInterval(function()
{
counter--;
if(counter== 0)
{
clearInterval(timer);
}
else
{
//Execute the CSS change function
styleChange();
}
}, 1000);
function styleChange()
{
document.getElementById("demo").innerHTML = (counter);
document.getElementById("demo").style.fontSize = "500%";
document.getElementById("demo").style.opacity = "0";
// In CSS "Demo" is given a transition of 1s to smooth out the animation"
}
下一个脚本不会在每次计数器时都重置样式,而是在样式之间切换,这不是我想要做的,但至少与第一个脚本不同,它会重复。它只是影响样式,如果它有效,我会添加计时器。
var myVar = setInterval(setStyle, 1000);
function setStyle() {
var x = document.getElementById("demo");
x.style.fontSize = x.style.fontSize == "100%" ? "500%" : "100%";
}
function stopStyle() {
clearInterval(myVar);
}
我想尝试使用 "for" 来遍历计数器的值,更改值更改时的样式,然后重置值,但我无法让它工作。从视觉上看,效果应该是这样的,但是是反向播放的,而不是在 acid-> https://www.youtube.com/watch?v=hsUKu9_Lr6U 上播放的。我大量借鉴了 w3schools 页面上关于 setInterval 和 clearInterval 的内容。
您不需要两个单独的间隔来使文本变大和变小。
相反,您可以使用 CSS 转换来为 font-size
从小到大设置动画,并使用 2 个嵌套 Window.requestAnimationFrame() 调用来正确计时,如下所示:
const counter = document.getElementById('counter');
let value = 11;
const intervalID = setInterval(() => {
const nextValue = --value;
if (nextValue === -1) {
clearInterval(intervalID);
return;
}
requestAnimationFrame(() => {
// Update the value and remove the `big` class in the next frame, so that
// the text becomes smaller again:
counter.textContent = nextValue;
counter.classList.remove('big');
requestAnimationFrame(() => {
// One more frame after that (so that the element has time to be re-rendered
// with the smaller font-size, add the `big` class again:
counter.classList.add('big');
});
});
}, 1000);
body {
margin: 0;
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
font-family: monospace;
}
#counter.big {
font-size: 500%;
opacity: 0;
transition: all linear 1s;
}
<div id="counter" class="big">10</div>
您甚至可以使用 CSS custom properties 轻松更改间隔延迟,同时使其与 CSS transition-duration
:
保持同步
const duration = 0.5; // In seconds
const counter = document.getElementById('counter');
let value = 11;
counter.style.setProperty('--transition-duration', `${ duration }s`);
const intervalID = setInterval(() => {
const nextValue = --value;
if (nextValue === -1) {
clearInterval(intervalID);
return;
}
requestAnimationFrame(() => {
// Update the value and remove the `big` class in the next frame, so that
// the text becomes smaller again:
counter.textContent = nextValue;
counter.classList.remove('big');
requestAnimationFrame(() => {
// One more frame after that (so that the element has time to be re-rendered
// with the smaller font-size, add the `big` class again:
counter.classList.add('big');
});
});
}, duration * 1000);
body {
margin: 0;
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
font-family: monospace;
}
#counter.big {
/* Default value: */
--transition-duration: 1s;
font-size: 500%;
opacity: 0;
transition: all linear var(--transition-duration);
}
<div id="counter" class="big"></div>
这是一个使用@keyframes 来实现相同目标的版本。
.running {
animation: growAndShow 1s linear infinite;
}
@keyframes growAndShow {
0%,
100% {
font-size: 100%;
opacity: 1;
}
50% {
font-size: 500%;
opacity: 0;
}
}
<p>A script on this page starts this clock:</p>
<p id="demo">Login in....</p>
<script>
var counter = 4;
var element = document.getElementById("demo")
var text = element.innerText;
element.innerText = text + counter;
var myVar = setInterval(runTimer, 1000);
element.classList.toggle('running');
function runTimer() {
element.innerText = text + --counter;
if (counter <= 0) stopTimer();
}
function stopTimer() {
clearTimeout(myVar);
element.classList.toggle('running');
}
</script>
您可以使用另一个 setInterval 来做到这一点,它会每 100 毫秒将字体大小减小 10px
我希望这会有所帮助
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre><code>//ele is same as your demo element
var ele=document.getElementById('demo');
//function that reduces the size of text of ele by 10px every 100ms
function redSize(){
var size=100;
var small=setInterval(()=>{
ele.style.fontSize=size+"px";size-=10;if(size==10) clearInterval(small);
},100)
}
function timer(count){
var counter=count;
var timer = setInterval(function(){
if(counter== 0)
{
clearInterval(timer);
}
else
{
ele.innerHTML=counter;
redSize();
}
counter--;
}, 1000);
}
timer(10);
<p id='demo'/>
我一直在尝试创建一个倒计时,每次计数器更改时都会为文本设置动画。我可以在开始时执行更改,但不确定如何清除更改并重复。
HTML & CSS
<!DOCTYPE html>
<html>
<head>
<!--meta http-equiv="refresh" content="4; url=index.php"-->
<style type="text/css">
p
{
transition: 1s;
font-size: 100%;
}
</style>
</head>
<body>
<p>A script on this page starts this clock:</p>
<p id="demo">Login in....</p>
<script>
//various javascript here
</script>
</body>
</html>
此脚本会在第一次计数时更改 CSS 一次,但不会在计数 2 或 1 时更改。
//Set the counter variable
var counter= 4;
//Set the timer to count the counter down
var timer = setInterval(function()
{
counter--;
if(counter== 0)
{
clearInterval(timer);
}
else
{
//Execute the CSS change function
styleChange();
}
}, 1000);
function styleChange()
{
document.getElementById("demo").innerHTML = (counter);
document.getElementById("demo").style.fontSize = "500%";
document.getElementById("demo").style.opacity = "0";
// In CSS "Demo" is given a transition of 1s to smooth out the animation"
}
下一个脚本不会在每次计数器时都重置样式,而是在样式之间切换,这不是我想要做的,但至少与第一个脚本不同,它会重复。它只是影响样式,如果它有效,我会添加计时器。
var myVar = setInterval(setStyle, 1000);
function setStyle() {
var x = document.getElementById("demo");
x.style.fontSize = x.style.fontSize == "100%" ? "500%" : "100%";
}
function stopStyle() {
clearInterval(myVar);
}
我想尝试使用 "for" 来遍历计数器的值,更改值更改时的样式,然后重置值,但我无法让它工作。从视觉上看,效果应该是这样的,但是是反向播放的,而不是在 acid-> https://www.youtube.com/watch?v=hsUKu9_Lr6U 上播放的。我大量借鉴了 w3schools 页面上关于 setInterval 和 clearInterval 的内容。
您不需要两个单独的间隔来使文本变大和变小。
相反,您可以使用 CSS 转换来为 font-size
从小到大设置动画,并使用 2 个嵌套 Window.requestAnimationFrame() 调用来正确计时,如下所示:
const counter = document.getElementById('counter');
let value = 11;
const intervalID = setInterval(() => {
const nextValue = --value;
if (nextValue === -1) {
clearInterval(intervalID);
return;
}
requestAnimationFrame(() => {
// Update the value and remove the `big` class in the next frame, so that
// the text becomes smaller again:
counter.textContent = nextValue;
counter.classList.remove('big');
requestAnimationFrame(() => {
// One more frame after that (so that the element has time to be re-rendered
// with the smaller font-size, add the `big` class again:
counter.classList.add('big');
});
});
}, 1000);
body {
margin: 0;
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
font-family: monospace;
}
#counter.big {
font-size: 500%;
opacity: 0;
transition: all linear 1s;
}
<div id="counter" class="big">10</div>
您甚至可以使用 CSS custom properties 轻松更改间隔延迟,同时使其与 CSS transition-duration
:
const duration = 0.5; // In seconds
const counter = document.getElementById('counter');
let value = 11;
counter.style.setProperty('--transition-duration', `${ duration }s`);
const intervalID = setInterval(() => {
const nextValue = --value;
if (nextValue === -1) {
clearInterval(intervalID);
return;
}
requestAnimationFrame(() => {
// Update the value and remove the `big` class in the next frame, so that
// the text becomes smaller again:
counter.textContent = nextValue;
counter.classList.remove('big');
requestAnimationFrame(() => {
// One more frame after that (so that the element has time to be re-rendered
// with the smaller font-size, add the `big` class again:
counter.classList.add('big');
});
});
}, duration * 1000);
body {
margin: 0;
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
font-family: monospace;
}
#counter.big {
/* Default value: */
--transition-duration: 1s;
font-size: 500%;
opacity: 0;
transition: all linear var(--transition-duration);
}
<div id="counter" class="big"></div>
这是一个使用@keyframes 来实现相同目标的版本。
.running {
animation: growAndShow 1s linear infinite;
}
@keyframes growAndShow {
0%,
100% {
font-size: 100%;
opacity: 1;
}
50% {
font-size: 500%;
opacity: 0;
}
}
<p>A script on this page starts this clock:</p>
<p id="demo">Login in....</p>
<script>
var counter = 4;
var element = document.getElementById("demo")
var text = element.innerText;
element.innerText = text + counter;
var myVar = setInterval(runTimer, 1000);
element.classList.toggle('running');
function runTimer() {
element.innerText = text + --counter;
if (counter <= 0) stopTimer();
}
function stopTimer() {
clearTimeout(myVar);
element.classList.toggle('running');
}
</script>
您可以使用另一个 setInterval 来做到这一点,它会每 100 毫秒将字体大小减小 10px 我希望这会有所帮助
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre><code>//ele is same as your demo element
var ele=document.getElementById('demo');
//function that reduces the size of text of ele by 10px every 100ms
function redSize(){
var size=100;
var small=setInterval(()=>{
ele.style.fontSize=size+"px";size-=10;if(size==10) clearInterval(small);
},100)
}
function timer(count){
var counter=count;
var timer = setInterval(function(){
if(counter== 0)
{
clearInterval(timer);
}
else
{
ele.innerHTML=counter;
redSize();
}
counter--;
}, 1000);
}
timer(10);
<p id='demo'/>