简体   繁体   中英

Create a Button that's border incrementally diminishes onClick and fires an event on time '0'

I found this great tool but it's awkward to implement in my project: https://github.com/vydimitrov/react-countdown-circle-timer

I want to create a reusable button component that onClick, starts a similar countdown effect with its border, giving the user a chance to 'undo' their decision (similar to forwarding a message in fb messenger). I can figure out the react logic but no clue where to start with css

Thanks in advance

Browsing the code of the component you mention, I noticed it uses an SVG element with animated stroke to create and animate the circular progress bar.

This article is my favourite one about this specific problem: https://css-tricks.com/building-progress-ring-quickly/

Here is the code from that article for future reference. This is not my code, kudos to the original author of the article:

 var circle = document.querySelector('circle'); var radius = circle.r.baseVal.value; var circumference = radius * 2 * Math.PI; circle.style.strokeDasharray = `${circumference} ${circumference}`; circle.style.strokeDashoffset = `${circumference}`; function setProgress(percent) { const offset = circumference - percent / 100 * circumference; circle.style.strokeDashoffset = offset; } const input = document.querySelector('input'); setProgress(input.value); input.addEventListener('change', function(e) { if (input.value < 101 && input.value > -1) { setProgress(input.value); } })
 html, body { background-color: #2962FF; display: flex; align-items: center; justify-content: center; height: 100%; position: relative; } .progress-ring { } .progress-ring__circle { transition: 0.35s stroke-dashoffset; // axis compensation transform: rotate(-90deg); transform-origin: 50% 50%; } input { position: fixed; top: 10px; left: 10px; width: 80px; }
 <svg class="progress-ring" width="120" height="120"> <circle class="progress-ring__circle" stroke="white" stroke-width="4" fill="transparent" r="52" cx="60" cy="60"/> </svg> <input value="35" type="number" step="5" min="0" max="100" placeholder="progress" >

This is a pure css pie timer which looks pretty similar to one of your timers mentioned in the link.

See it in full screen

 var time = 11; { var func = setInterval(function() { if (time != 0) { document.getElementsByClassName('time')[0].innerHTML = time; time--; if (time < 5) { document.getElementsByClassName('warning')[0].style.display = "block"; } } else { document.getElementsByClassName('time')[0].innerHTML = "0"; document.getElementsByClassName('warning')[0].style.display = "none"; clearInterval(func); } }, 1000); }
 .timer { height: 200px; width: 200px; border-radius: 50%; background-color: black; animation: time 5s infinite; margin-left: 570px; margin-top: 200px; } .bar { position: absolute; } .left_progress { position: absolute; height: 200px; width: 200px; background: linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%); border-radius: 50%; clip: rect(0px 100px 200px 0px); animation: rotate_right 6s 6s linear both; } @keyframes rotate_right { 100% { transform: rotateZ(180deg); } } .left_progress_bar { position: absolute; height: 200px; width: 200px; background-color: #E9E9E9; border-radius: 50%; clip: rect(0px 100px 200px 0px); z-index: 1; animation: mid-way 4s linear both; } .right_progress { position: absolute; height: 200px; width: 200px; background-color: #E9E9E9; border-radius: 50%; clip: rect(0px 100px 200px 0px); transform: rotateZ(180deg); animation: rotate_left 6s linear both; } @keyframes rotate_left { 100% { transform: rotateZ(360deg); } } .right_progress_bar { position: absolute; height: 200px; width: 200px; background: linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%); border-radius: 50%; clip: rect(0px 100px 200px 0px); transform: rotateZ(180deg); z-index: 1; } .main_content { position: absolute; height: 180px; width: 180px; border-radius: 50%; background-color: white; z-index: 4; margin-top: 10px; margin-left: 10px; font-family: 'arial'; text-align: center; } .timer_content { position: absolute; margin-top: 40px; margin-left: 45px; } .content { font-size: 15px; margin: 0px; color: #6B6C6D; } .time { font-size: 55px; margin: 0px; background: -webkit-linear-gradient(90deg, #00d2ff 0%, #3a47d5 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .warning { position: absolute; height: 180px; width: 180px; border-radius: 50%; background-color: #DBDBDB; animation: warning_bell 1s infinite; display: none; } @keyframes warning_bell { from { transform: scale(0); opacity: 1; } to { transform: scale(1); opacity: 0; } }
 <div class="timer"> <div class="right_progress_bar"> <div class="right_progress"></div> </div> <div class="left_progress_bar"> <div class="left_progress"></div> </div> <div class="main_content"> <div class="warning"></div> <div class="timer_content"> <p class="content">You can do in</p> <p class="time">12</p> <p class="content">seconds</p> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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