简体   繁体   English

CSS:在计时器上暂停 animation

[英]CSS: Pause animation on timer

I am implementing a time counter.我正在实施一个计时器。

The objective is that user can start the timer, and when he feels like it, he can pause or continue the timer.目的是用户可以启动计时器,当他觉得需要时,他可以暂停或继续计时器。

The difficulty I encountered was pausing the SVG animation.我遇到的困难是暂停 SVG animation。

I followed this article , however it does not work.我关注了这篇文章,但是它不起作用。

Any suggestions?有什么建议么?

CODE代码

 (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>

CODE代码

Code change with the suggestion of this answer .根据此答案的建议更改代码。

The problem now is that the animation got faster in the middle and slower at the beginning and at the end, so it will not hit the right spots on the "clock"现在的问题是,animation 在中间变得更快,在开始和结束时变慢,所以它不会在“时钟”上击中正确的位置

 (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>

I haven't tested it;我没有测试过; just digging up old knowledge.只是挖掘旧知识。

With animation: fill 1s;animation: fill 1s; shorthand notation速记符号
you are also messing with the animation-play-state setting.您还弄乱了animation-play-state设置。

Try using all separate properties: https://developer.mozilla.org/en-US/docs/Web/CSS/animation尝试使用所有单独的属性: https://developer.mozilla.org/en-US/docs/Web/CSS/animation

and a animation-play-state: running (or paused) to start with和一个animation-play-state: running (或暂停)开始

Update更新

If I change your CSS to:如果我将您的 CSS 更改为:

    xanimation: fill 1s;
    animation-name: fill;
    animation-duration:60s;
    animation-play-state:paused;

Your toggle does something你的切换做某事

So play-state toggle works所以播放状态切换有效

Now you have to make your CSS and SVG do what you want现在你必须让你的 CSS 和 SVG 做你想做的事

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM