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 class="lockpic" 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"/>
                </g>
            </svg>
            <svg class="lockpic" id="newshackle" viewBox="0 0 120 120" width="100%" height="100%">
                <g>
                    <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:3; 
}
.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:98%;
    height:98%;
    margin:50% 0 0 50%;
    top:-49%;
    left:-49%;
    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 #newshackle{
    transform:rotatey(180deg);
    -webkit-transform:rotatey(180deg);
}
#newshackle{
    transform:rotatey(0deg);
    -webkit-transform:rotatey(0deg);
    transform-origin:35% 0%;
    -webkit-transform-origin:35% 0%;
    transition: transform 250ms linear;
    -webkit-transition: -webkit-transform 250ms linear;
    -webkit-transition-delay:100ms;
    transition-delay:100ms;
    
}
.lockback:hover #shackle{
   ...

JavaScript

(function setEvents(){
    var clicked=0;
    var intId=0;
    var int2Id=0;
    var aperture=0;
    var angle=0;
    var dAperture=12;
    var dAngle=7.2;
    var transformFunc=((/^((?!chrome).)*safari/i.test(navigator.userAgent))?"-webkit-transform":"transform");
    var shackles=document.getElementById("newshackle");
    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){
            shackles.style[transformFunc]="";
            shackle.style.opacity="";
            shopened.style.opacity="";
            lockback.style[transformFunc]="";
        }else{
            shackles.style[transformFunc]="rotatey(180deg)";
            shackle.style.opacity=0;
            shopened.style.opacity=1;
            lockback.style[transformFunc]="scale(1,1)";
        }
    }
    function setAperture(ang){
        ang%=360;
        var ex=100+(100*Math.cos(6.28318531*ang/360.0));
        var ey=100+(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 padlockClick(evt){
    if(clicked){
        clicked=0;
        setUnlock(true);
        clearInterval(intId);
        setAperture(0);
        clearInterval(int2Id);
       ...