我正在实现一个时间计数器。
目标是用户可以启动计时器,并且当他愿意时,他可以暂停或继续计时器。
我遇到的困难是暂停 SVG 动画。
我关注了这个article ,但是它不起作用。
有什么建议吗?
代码
(function() {
const start = document.querySelector( '.start' ),
togglePause = document.querySelector( '.pause' ),
seconds = 60;
function format( seconds ) {
var sec = Math.floor( seconds % 60 ),
min = Math.floor( seconds / 60 );
secdisp = sec;
mindisp = min;
if( min === 0 && sec === 0 ) {
clearInterval( countdown );
} else if ( secdisp === 0 ) {
min--;
sec = 0;
}
return mindisp + ':' + ( secdisp < 10 ? '0' + secdisp : secdisp );
}
function tickdown( seconds ) {
var mod = Math.floor( seconds % 60 ),
min = Math.floor( seconds / 60 ) - ( mod === 0 ? 1 : 0 ),
sec = ( mod ? 60 - mod : 0 );
var tick = () => {
seconds--;
document.getElementById('time').innerHTML = format( seconds );
};
tick();
countdown = setInterval( tick, 1000 );
}
document.getElementById('time').innerHTML = format( seconds );
start.addEventListener('click', () => {
var gauge = document.querySelector( '.timer-gauge' ),
frame = document.querySelector( 'html' );
tickdown( seconds );
gauge.style.transitionDuration = seconds + 's';
gauge.classList.add('ticking');
});
togglePause.addEventListener( 'click', () => {
var gauge = document.querySelector( '.timer-gauge' );
const running = gauge.style.animationPlayState === 'running';
gauge.style.animationPlayState = running ? 'paused' : 'running';
});
}());
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html {
background: linear-gradient(125deg, #5967c3 0%,#76b8d6 100%);
height: 100vh;
width: 100vw;
max-height: 100vh;
max-width: 100vw;
}
html:after {
content: " ";
position: absolute;
height: 100%;
left: 0;
top: 0;
opacity: 0;
transition: opacity .1s linear;
width: 100%;
z-index: 1;
pointer-events: none;
}
html.started:after {
background: linear-gradient(125deg, #52b670 0%,#84c86d 100%);
opacity: 1;
}
body {
margin: 0;
}
svg {
position: absolute;
width: 100%;
height: 100%;
padding: 2%;
pointer-events: none;
z-index: 2;
}
.main {
max-width: 100%;
}
.chart-gauge {
font-size: 1.5rem;
text-anchor: middle;
dominant-baseline: central;
alignment-baseline: middle;
stroke-linecap: round;
}
.timer-time {
fill: rgba(255,255,255,.6);
}
.timer-backdrop {
transform: rotate(-90deg);
transform-origin: center;
fill: none;
stroke: rgba(255,255,255,.2);
stroke-width: 5;
}
.timer-gauge {
transform: rotate(-270deg) scaleX(-1);
transform-origin: center;
fill: none;
stroke: rgba(255,255,255,.75);
stroke-width: 5;
animation: fill 1s;
animation-iteration-count: 1;
stroke-dashoffset: 0;
}
.ticking {
stroke-dashoffset: 360;
transition-timing-function: linear;
}
@keyframes fill {
0% { stroke-dashoffset: 360; }
100% { stroke-dashoffset: 0; }
}
<div class="main">
<svg viewBox="0 0 120 120" class="chart-gauge" fill="none" stroke-width="2">
<circle class="timer-backdrop" stroke-dasharray="360" r="57.32" cx="60" cy="60"></circle>
<circle class="timer-gauge" stroke-dasharray="360" r="57.32" cx="60" cy="60"></circle>
<text y="50%" x="50%" id="time" class="timer-time">1:00</text>
</svg>
<button class="start">Start</button>
</div>
<button class="pause">Toggle Pause</button>
代码
根据此 answer 的建议更改代码.
现在的问题是动画在中间变快,在开始和结束时变慢,因此它不会到达“时钟”上的正确位置
(function() {
const start = document.querySelector( '.start' ),
togglePause = document.querySelector( '.pause' ),
seconds = 60;
function format( seconds ) {
var sec = Math.floor( seconds % 60 ),
min = Math.floor( seconds / 60 );
secdisp = sec;
mindisp = min;
if( min === 0 && sec === 0 ) {
clearInterval( countdown );
} else if ( secdisp === 0 ) {
min--;
sec = 0;
}
return mindisp + ':' + ( secdisp < 10 ? '0' + secdisp : secdisp );
}
function tickdown( seconds ) {
var mod = Math.floor( seconds % 60 ),
min = Math.floor( seconds / 60 ) - ( mod === 0 ? 1 : 0 ),
sec = ( mod ? 60 - mod : 0 );
var tick = () => {
seconds--;
document.getElementById('time').innerHTML = format( seconds );
};
tick();
countdown = setInterval( tick, 1000 );
}
document.getElementById('time').innerHTML = format( seconds );
start.addEventListener('click', () => {
var gauge = document.querySelector( '.timer-gauge' ),
frame = document.querySelector( 'html' );
tickdown( seconds );
gauge.style.animationDuration = seconds + 's';
gauge.classList.add('ticking');
});
togglePause.addEventListener( 'click', () => {
var gauge = document.querySelector( '.timer-gauge' );
const running = gauge.style.animationPlayState === 'running';
gauge.style.animationPlayState = running ? 'paused' : 'running';
});
}());
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html {
background: linear-gradient(125deg, #5967c3 0%,#76b8d6 100%);
height: 100vh;
width: 100vw;
max-height: 100vh;
max-width: 100vw;
}
html:after {
content: " ";
position: absolute;
height: 100%;
left: 0;
top: 0;
opacity: 0;
transition: opacity .1s linear;
width: 100%;
z-index: 1;
pointer-events: none;
}
html.started:after {
background: linear-gradient(125deg, #52b670 0%,#84c86d 100%);
opacity: 1;
}
body {
margin: 0;
}
svg {
position: absolute;
width: 100%;
height: 100%;
padding: 2%;
pointer-events: none;
z-index: 2;
}
.main {
max-width: 100%;
}
.chart-gauge {
font-size: 1.5rem;
text-anchor: middle;
dominant-baseline: central;
alignment-baseline: middle;
stroke-linecap: round;
}
.timer-time {
fill: rgba(255,255,255,.6);
}
.timer-backdrop {
transform: rotate(-90deg);
transform-origin: center;
fill: none;
stroke: rgba(255,255,255,.2);
stroke-width: 5;
}
.timer-gauge {
transform: rotate(-270deg) scaleX(-1);
transform-origin: center;
fill: none;
stroke: rgba(255,255,255,.75);
stroke-width: 5;
animation-name: initial-fill;
animation-duration: 1s;
animation-iteration-count: 1;
stroke-dashoffset: 0;
}
.ticking {
animation-name: fill;
stroke-dashoffset: 360;
transition-timing-function: linear;
}
@keyframes initial-fill {
0% { stroke-dashoffset: 360; }
100% { stroke-dashoffset: 0; }
}
@keyframes fill {
0% { stroke-dashoffset: 0; }
100% { stroke-dashoffset: 360; }
}
<div class="main">
<svg viewBox="0 0 120 120" class="chart-gauge" fill="none" stroke-width="2">
<circle class="timer-backdrop" stroke-dasharray="360" r="57.32" cx="60" cy="60"></circle>
<circle class="timer-gauge" stroke-dasharray="360" r="57.32" cx="60" cy="60"></circle>
<text y="50%" x="50%" id="time" class="timer-time">1:00</text>
</svg>
<button class="start">Start</button>
</div>
<button class="pause">Toggle Pause</button>
</div>
最佳答案
我还没有测试过;只是挖掘旧知识。
使用动画:填充1s;
简写表示法
您还弄乱了 animation-play-state
设置。
尝试使用所有单独的属性:https://developer.mozilla.org/en-US/docs/Web/CSS/animation
和一个animation-play-state: running
(或暂停)开始
更新
如果我将你的 CSS 更改为:
xanimation: fill 1s;
animation-name: fill;
animation-duration:60s;
animation-play-state:paused;
您的切换开关可以执行某些操作
所以播放状态切换有效
现在你必须让你的 CSS 和 SVG 做你想做的事情
关于javascript - CSS:在计时器上暂停动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67125030/