CSS: Implement pause functionality for animations with a timer

I'm working on a timer implementation that allows users to start the timer and pause or continue it whenever they want.

I faced a challenge when trying to pause the SVG animation.

I tried following this article, but it didn't work as expected.

Any suggestions?

CODE

(function() {
            const btnStart = document.querySelector('.start'),
                btnPause = document.querySelector('.pause'),
                seconds = 60;
            
            function formatTime(seconds) {
                var sec = Math.floor(seconds % 60),
                    min = Math.floor(seconds / 60);
                    
                return min + ':' + (sec < 10 ? '0' + sec : sec);
            }
        
            function countdown(seconds) {
                var tick = () => {
                    seconds--;
                    document.getElementById('time').innerHTML = formatTime(seconds);
                };
                
                tick();
                var timer = setInterval(tick, 1000);

                if (seconds <= 0) {
                    clearInterval(timer);
                } 
            }

            document.getElementById('time').innerHTML = formatTime(seconds);

            btnStart.addEventListener('click', () => {
                var gauge = document.querySelector('.timer-gauge');
                countdown(seconds);
                gauge.classList.add('ticking');
            });
  
            btnPause.addEventListener('click', () => {
                var gauge = document.querySelector('.timer-gauge');
                gauge.classList.toggle('paused');
            });

        }());
* {
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
        }
        // CSS styles here...
        

CODE

After implementing some changes based on this answer, the animation became inconsistent; speeding up in the middle and slowing down at the beginning and end. This affects its synchronization with the "clock" visual representation.

(function() {
            const btnStart = document.querySelector('.start'),
                btnPause = document.querySelector('.pause'),
                seconds = 60;

            function formatTime(seconds) {
                var sec = Math.floor(seconds % 60),
                    min = Math.floor(seconds / 60);

                return min + ':' + (sec < 10 ? '0' + sec : sec);
            }

            function countdown(seconds) {
                var tick = () => {
                    seconds--;
                    document.getElementById('time').innerHTML = formatTime(seconds);
                };

                tick();
                var timer = setInterval(tick, 1000);

                if (seconds <= 0) {
                    clearInterval(timer);
                }
            }

            document.getElementById('time').innerHTML = formatTime(seconds);

            btnStart.addEventListener('click', () => {
                var gauge = document.querySelector('.timer-gauge');
                countdown(seconds);
                gauge.classList.add('ticking');
            });

            btnPause.addEventListener('click', () => {
                var gauge = document.querySelector('.timer-gauge');
                gauge.classList.toggle('paused');
            });

        }());
* {
            -webkit-box-sizing: border-box;
            box-sizing: border-box;
        }
        // More CSS styles here...
        

Answer №1

I haven't personally tried this method, but I am recalling some older information.

By using the animation: fill 1s; in shorthand form, you are also adjusting the animation-play-state property.

To avoid conflicts, consider utilizing separate properties as suggested here: https://developer.mozilla.org/en-US/docs/Web/CSS/animation

Add a specific animation-play-state: running (or paused) to initiate the animation correctly.

Update

If you modify your CSS to:

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

Your toggle functionality will have an effect.

The play-state toggle seems to be functioning properly.

You may now proceed with aligning your CSS and SVG elements according to your desired outcome.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Linking MySQL Database to Javascript Quiz (Novice)

After constructing the database for my quiz, I am facing an issue with getting the user's answers to be stored in the database. Although the quiz functions properly on my browser and questions can be answered, I am unable to calculate the final score ...

Dynamic styling updates on page refresh in Next.js

There is a strange issue with my styling that I can't seem to figure out. I have a NavBar set to be 20vh in height and an image set to be 100% in width. However, whenever I refresh the page, the NavBar height decreases and the image width increases si ...

challenge with altering data in transmission when using the GET method

$('.textedit').editable('/webpage/skeleton/edit_text/text/process', { loadurl: '/webpage/skeleton/edit_text/loadraw', loaddata: {id: $(this).attr('id'), client: $(this).data('client')}, submitda ...

Issues with div and hyperlinks/forms

I am currently working on creating a left sidebar in my HTML code, but I am still new to this. In the div for the sidebar, I have three buttons. However, Weebly keeps notifying me of an issue with the <a> tag, and the second button's link appear ...

What is the method for determining the coordinate range in a three.js environment?

When developing a scene using html and javascript, incorporating a camera, renderer, and displaying the scene in a browser, how can one determine the visible range of the scene? In a specific scenario where only a 2-dimensional x/y scene with objects is b ...

Manipulate Images Efficiently with jQuery

Are there any jQuery plugins or JavaScript controls available that can display an array of images, with the option to delete an image based on user action? For example, something similar to this: , but with a dedicated delete button on each image. One ad ...

Unable to establish a connection to the server while handling a jQuery Ajax error

I'm in the process of pinpointing an issue that occurs when submitting an Ajax request through jQuery and encountering a failed connection to the server. The scenario involves loading a page from the server, then deliberately disconnecting the network ...

Create an intricate table design using CSS grid and incorporate nested vue v-for loops for dynamic content rendering

I have data that is nested and I want to display it in a tabular format. Here is an example of the data; in the actual application, there could be dozens of entries in rows. <script> export default { name: 'Example', data () { retu ...

Exploring Updates in Two Objects Using a Loop in JavaScript

Two different Objects are structured as follows: Obj1: { 0: {name:"", id: 0}, 1: {"age": "", id:0}, 2: {name:"", id: 1}, 3: {"age": "", id:1}, } After triggering a property, the structure ch ...

Enabling JavaScript functions to accept a variable number of arguments

I am looking to enhance the versatility of the function below by enabling it to accept multiple callbacks to other functions if they are specified in the arguments. $(function() { function icisDashBox(colorElem, thisWidth, thisHeight, completeCallBack ...

CORS issue encountered by specific user visiting the hosted website

I recently developed a bot chatting website using Django and React, which I have hosted on HOSTINGER. The backend is being hosted using VPS. However, some users are able to see the full website while others encounter CORS errors where the APIs are not func ...

Executing a function within a loop

I'm having trouble understanding the output. The first two sets of results (func01 1 and func2 01 - func2 05) make sense to me, but everything else is confusing. As far as I know, after the first iteration of the for loop in func01(), i becomes 2 and ...

Splitting the page into four sections with a unique H layout using CSS styling

Attempting to create an H page layout: body { background-color: grey; background-size: 100%; background-repeat: no-repeat; } html, body { height: 100%; margin: 0px; } .a { float: left; width: 25%; height: 100%; border: 1px solid blue ...

Scrollbar malfunction in Angular and Bootstrap主 The main scrollbar in Angular and Bootstrap is un

I am currently facing an issue with my Angular app using Bootstrap 5. The main html/body scrollbar does not work when elements overflow the view. I have tried various solutions such as setting a fixed height, adjusting overflow-y to scroll or auto for body ...

CSS image replacement; won't render properly

I'm currently working on implementing a hover image swap effect for my website gallery. The CSS code I have so far is below. While the original images in my HTML file are displaying correctly, the hover functionality is not working as expected. CSS: ...

Hide Panels on amcharts

Is there a way to toggle the visibility of panels without having to delete and recreate them each time? I haven't been able to find any examples online. A big thank you to @Robbert for the helpful reply! I found a way to hide a panel using this code ...

Rotate the mat-select arrow when the dropdown opens (moving in both upward and downward directions)

Currently, I have a mat-select dropdown icon arrow that toggles facing up or down based on user clicks. However, after selecting an option and closing the dropdown, the arrow remains in the upward position unless further clicked and held. I have attempted ...

Creating a hover effect instead of a click event in a Bootstrap 4 dropdown menu

Looking to create a hover effect instead of a click in the bootstrap dropdown menu? Past answers lack jQuery code that can simply be copied and pasted into your script for optimal results. Additionally, previous solutions were written for older versions o ...

Transitioning side-by-side images into stacked vertical images for mobile devices

I am struggling to stack 4 side by side images on top of each other along with text over the images when viewing on mobile, instead of shrinking them. Despite my attempts at adjusting the styles, I have not been successful in achieving this desired layout. ...

The content division does not have a set position

The content div is not adapting to different screen sizes properly. As the width and height of the browser shrink, it's overlapping with the header and footer. I'm using flex but I'm unsure if I'm implementing it correctly. display: ...