JSFiddle - React, Tailwind, and code Playground
by Felis Catus
HTML
<span class="instr">Click padlock to unlock/relock!</span>
<div class="container">
<div class="spinner">
<svg width="100%" height="100%" viewBox="-1 -1 202 202">
<path id="spinarch" d="M 1,100" style="fill:none"/>
</svg>
</div>
<div class="lockback">
<div class="padlock">
<svg viewBox="0 0 120 120" width="100%" height="100%">
<g>
<path id="lock" fill="#FFFFFF" d="M87.1,54.9H33.5c-4.9,0-9,3.9-9,8.8v41.2c0,4.9,4.1,8.8,9,8.8h53.9c4.9,0,9-3.9,9-8.8V63.7C96.1,58.8,92,54.9,87.1,54.9z"/>
<path class="unlockable" id="shackle" fill="#ffffff" d="M35.5,50.2h4.7c1.2,0,2-1,2-2V31.3c0-9,6.6-16,15.6-17.2c10.9-1.4,20.3,7,20.3,17.4v16.4c0,1.2,1,2,2,2h4.7c1.2,0,2-0.8,2-2V31.1c0-14.1-10.9-25.2-25.2-26c-15.6-1-28.7,11.3-28.7,26.2v16.6 C33.5,49.1,34.3,50.2,35.5,50.2z"/>
<path class="unlockable" id="opened" fill="#ffffff" d="m 35.5,50.2 4.7,0 c 1.2,0 2,-1 2,-2 l 0,-16.9 c 0,-9 6.6,-16 15.6,-17.2 10.9,-1.4 20.3,7 20.3,17.4 l 0,3.45635 c 0,1.2 1,2 2,2 l 4.7,0 c 1.2,0 2,-0.8 2,-2 L 86.8,31.1 C 86.8,17 75.9,5.9 61.6,5.1 46,4.1 32.9,16.4 32.9,31.3 l 0,16.6 c 0.6,1.2 1.4,2.3 2.6,2.3 z"/>
</g>
</svg>
</div>
</div>
</div>
CSS
/*colors*/
#spinarch{
stroke:#3fb1e5;
stroke-width:2;
}
.container{
background:transparent;
}
.lockback{
background:#3fb1e5;
}
/*for example only. container has to be square.*/
body{
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)),url("http://www.traipse.com/penrose_tiles/penrose_tiles.gif");
}
.instr{
text-shadow:0 0 2px white,0 0 2px white;
}
.container{
width:100px;
height:100px;
margin:100px 100px;
}
/*structure - don't touch*/
.container{
position:relative;
overflow:hidden;
}
.spinner{
position:absolute;
background:inherit;
width:100%;
height:100%;
margin:50% 0 0 50%;
top:-50%;
left:-50%;
transform:rotate(0deg);
-webkit-transform:rotate(0deg);
border-radius:50%;
}
.lockback{
position:absolute;
width:88%;
height:88%;
margin:50% 0 0 50%;
top:-44%;
left:-44%;
border-radius:50%;
overflow:hidden;
transition:transform 100ms ease/*cubic-bezier(.42,0,.58,1)*/;
-webkit-transition:-webkit-transform 100ms cubic-bezier(.42,0,.58,1);
transform:scale(0.83,0.83);
-webkit-transform:scale(0.83,0.83);
transition-delay:250ms;
-webkit-transition-delay:250ms;
}
.padlock{
position:absolute;
width:76%;
height:56%;
margin:50% 0 0 50%;
top:-28%;
left:-38%;
}
.lockback:hover{
transform:scale(1,1);
-webkit-transform:scale(1,1);
/*transition-timing-function:linear;*/
-webkit-transition-delay:0ms;
transition-delay:0ms;
}
.lockback:hover .unlockable{
transform:rotatey(180deg) translate(-8px,0px);
-webkit-transform:rotatey(180deg) translate(-8px,0px);
}
.lockback:hover #shackle{
opacity:0;
}
.unlockable{
transform:rotatex(0deg) translate(0px,0px);
transform-origin:1% 1%;
transition: transform 250ms linear, opacity 250ms cubic-bezier(1,0,0,1);
transition-delay:100ms,100ms;
-webkit-transition-delay:100ms,100ms;
...
JavaScript
(function setEvents(){
var clicked=0;
var intId=0;
var int2Id=0;
var aperture=0;
var angle=0;
var dAperture=10;
var transformFunc=((/^((?!chrome).)*safari/i.test(navigator.userAgent))?"-webkit-transform":"transform");
var shackles=document.getElementsByClassName("unlockable");
var shackle=document.getElementById("shackle");
var shopened=document.getElementById("opened");
var arc=document.getElementById("spinarch");
var spinner=document.getElementsByClassName("spinner")[0];
var lockback=document.getElementsByClassName("lockback")[0];
function setUnlock(locked){
if(locked){
for(var i=0;i<shackles.length;i++){
shackles[i].style[transformFunc]="";
}
shackle.style.opacity="";
shopened.style.opacity="";
lockback.style[transformFunc]="";
}else{
for(var i=0;i<shackles.length;i++){
shackles[i].style[transformFunc]="rotatey(180deg) translate(-8px,0px)";
}
shackle.style.opacity=0;
shopened.style.opacity=1;
lockback.style[transformFunc]="scale(1,1)";
}
}
function setAperture(ang){
ang%=360;
var ex=100+Math.round(100*Math.cos(6.28318531*ang/360.0));
var ey=100+Math.round(100*Math.sin(6.28318531*ang/360.0));
if(ang<=90){
arc.setAttribute("d","M 200,100 A 100,100 0 0,1 "+ex+","+ey);
}else if(ang<=180){
arc.setAttribute("d","M 200,100 A 100,100 0 0,1 100,200 A 100,100 0 0,1 "+ex+","+ey);
}else if(ang<=270){
arc.setAttribute("d","M 200,100 A 100,100 0 0,1 100,200 A 100,100 0 0,1 0,100 A 100,100 0 0,1 "+ex+","+ey);
}else{
arc.setAttribute("d","M 200,100 A 100,100 0 0,1 100,200 A 100,100 0 0,1 0,100 A 100,100 0 0,1 100,0 A 100,100 0 0,1 "+ex+","+ey);
}
}
document.getElementsByClassName("lockback")[0].onclick=function...