A Pen by Marco Aurélio da Silva on CodePen.
Created
October 13, 2020 02:28
-
-
Save marcoonroad/699e968fb2da0a295c1c72d6d1c32c9c to your computer and use it in GitHub Desktop.
OTP/2-factor code spinner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://unpkg.com/@otplib/preset-browser@^12.0.0/buffer.js"></script> | |
<script src="https://unpkg.com/@otplib/preset-browser@^12.0.0/index.js"></script> | |
<div class="wrapper"> | |
<div class="noop"> | |
<div class="background-spin-loop"></div> | |
<div class="spin-text"> | |
<div><span id="otp-code">123456</span></div> | |
</div> | |
<div class="spin-wrapper"> | |
<div class="noop"> | |
<div class="spin-container spin-cursor-container" id="spin-cursor-container-id"> | |
<div class="spin spin-cursor" id="spin-cursor-id"></div> | |
</div> | |
<div class="spin-container spin-slices-container" id="spin-slices-container-id"> | |
<div class="spin spin-slices" id="spin-slices-id"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script type="text/javascript"> | |
(function () { | |
function getSeconds() { | |
return (new Date()).getSeconds(); | |
} | |
var auth = window.otplib.authenticator; | |
var secret = "dummysecretdummy"; | |
function computeToken () { | |
var token = auth.generate(secret); | |
var otpTag = document.getElementById("otp-code"); | |
otpTag.textContent = token; | |
console.log((new Date().toString()), token); | |
} | |
var timeout = 30 - (getSeconds() % 30); | |
computeToken(); | |
var animationDelay = '-' + (30 - timeout).toString() + 's'; | |
document.getElementById('spin-slices-id').style.animationDelay = animationDelay; | |
document.getElementById('spin-slices-container-id').style.animationDelay = animationDelay; | |
document.getElementById('spin-cursor-id').style.animationDelay = animationDelay; | |
document.getElementById('spin-cursor-container-id').style.animationDelay = animationDelay; | |
if (!timeout) { | |
setInterval(computeToken, 30000); | |
return; | |
} | |
setTimeout(function () { | |
computeToken(); | |
setInterval(computeToken, 30000); | |
}, timeout * 1000); | |
})(); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:root { | |
--bg: gray; | |
--fg: black; | |
--size: 200px; | |
--period: 30s; | |
--border-width: 10px; | |
--font-size: 2em; | |
} | |
.wrapper { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
padding: 0 auto; | |
height: var(--size); | |
overflow: hidden; | |
} | |
.wrapper div.noop { | |
width: var(--size); | |
height: var(--size); | |
overflow: hidden; | |
} | |
.spin-wrapper { | |
position: absolute; | |
} | |
.spin-wrapper div.noop { | |
overflow: hidden; | |
width: var(--size); | |
height: var(--size); | |
} | |
.spin-container { | |
transform: rotate(-45deg); | |
position: absolute; | |
overflow: hidden; | |
} | |
@keyframes spin-goes-up { | |
0%, 74% { z-index: -200; } | |
75%, 100% { z-index: 500; } | |
} | |
@keyframes spin-goes-down { | |
0%, 74% { z-index: 200; } | |
75%, 100% { z-index: -500; } | |
} | |
.spin-cursor-container { | |
animation: spin-goes-up var(--period) infinite linear; | |
} | |
.spin-slices-container { | |
animation: spin-goes-down var(--period) infinite linear; | |
} | |
.spin-text { | |
display: block; | |
position: absolute; | |
height: var(--size); | |
width: var(--size); | |
z-index: -1000; | |
margin-top: 0px; | |
margin-left: 0px; | |
border-radius: 50%; | |
border-width: var(--border-width); | |
border-style: solid; | |
border-color: transparent; | |
} | |
.background-spin-loop { | |
border-color: var(--bg); | |
border-style: solid; | |
border-width: var(--border-width); | |
border-radius: 50%; | |
transform: rotate(-45deg); | |
position: absolute; | |
width: var(--size); | |
height: var(--size); | |
z-index: -7000; | |
} | |
.print-border { | |
border: solid 1px red; | |
} | |
.spin-text div { | |
display: block; | |
width: var(--size); | |
height: var(--size); | |
} | |
.spin-text span { | |
font-weight: bold; | |
display: inline-block; | |
font-family: monospace; | |
font-size: var(--font-size); | |
text-align: center; | |
vertical-align: middle; | |
height: var(--size); | |
width: var(--size); | |
line-height: var(--size); | |
} | |
span.code { | |
transform: rotate(45deg); | |
} | |
@-webkit-keyframes rotation-animation { | |
0% { transform: rotate(0deg); } | |
25% { transform: rotate(90deg); } | |
50% { transform: rotate(180deg); } | |
75% { transform: rotate(270deg); } | |
100% { transform: rotate(360deg); } | |
} | |
.spin { | |
width: var(--size); | |
height: var(--size); | |
border-style: solid; | |
border-width: var(--border-width); | |
border-color: transparent; | |
border-radius: 50%; | |
} | |
.spin-cursor { | |
border-top-color: var(--fg) !important; | |
border-right-color: transparent !important; | |
border-bottom-color: transparent !important; | |
border-left-color: transparent !important; | |
animation: rotation-animation var(--period) infinite linear; | |
} | |
@keyframes slices-animation { | |
0%, 24% { | |
border-top-color: var(--bg); | |
border-right-color: transparent; | |
border-bottom-color: transparent; | |
border-left-color: transparent; | |
} | |
25%, 49% { | |
border-top-color: var(--bg); | |
border-right-color: var(--fg); | |
border-bottom-color: transparent; | |
border-left-color: transparent; | |
} | |
50%, 74% { | |
border-top-color: var(--bg); | |
border-right-color: var(--fg); | |
border-bottom-color: var(--fg); | |
border-left-color: transparent; | |
} | |
75% { | |
border-top-color: var(--bg); | |
border-right-color: var(--fg); | |
border-bottom-color: var(--fg); | |
border-left-color: var(--fg); | |
} | |
76%, 100% { | |
border-top-color: var(--bg); | |
border-right-color: var(--fg); | |
border-bottom-color: var(--fg); | |
border-left-color: var(--fg); | |
} | |
} | |
.spin-slices { | |
animation: slices-animation var(--period) infinite linear; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment