JSFiddle - React, Tailwind, and code Playground

by Felis Catus

HTML

<link href='http://fonts.googleapis.com/css?family=PT+Sans:400,400italic' rel='stylesheet' type='text/css'>
<div id='container'>
    <svg id="torprogress" height="100%" width="100%" viewBox="0 0 600 400" preserveAspectRatio="none">
        <g transform="translate(300,200)">
            <path id="captionpath" d="M-290,-120 L0,-120"/>
            <text x="0" y="-120" id="captiontext" font-size="38" text-anchor="middle">    
                <tspan style="opacity:0">Caption caption caption Caption caption!</tspan>
                <textPath id="getme" startOffset="50%" xlink:href="#captionpath">Caption caption caption Caption caption!</textPath>
            </text>
            <path id="shutter" d="M0,0 L0,-500 z" />
            <path id="grid" d="M0,-500 L0,500 M-500,0 L500,0" />
            <g id="stepper">
                <g id="aperture" transform="rotate(-20)">
                    <g class="spinner" transform="rotate(30)">
                        <path d="M85,0 A85,85 0 0,1 0,85 A85,85 0 0,1 -85 0 A85,85 0 0,1 0,-85 A85,85 0 0,1 73,-44" />
                    </g>
                    <g transform="scale(-1,1)">
                        <g class="spinner" transform="rotate(30)">
                            <path d="M95,0 A95,95 0 0,1 0,95 A95,95 0 0,1 -95 0 A95,95 0 0,1 0,-95 A95,95 0 0,1 82,-47" />
                        </g>
                    </g>
                </g>
                <text id="stage" x="0" y="0" font-size="130" dominant-baseline="middle" text-anchor="middle">5</text>
            </g>
            <text id="status" x="0" y="140" font-size="18" text-anchor="middle">blabla</text>
            <text id="speed" x="0" y="160" font-size="16" text-anchor="middle">190 tbps</text>
        </g>
    </svg>
</div>

CSS

@font-face...

JavaScript

(function init(){
    $('#container').click(function(evt){
        var txt=$('#captiontext tspan')[0];
        var pth=$('#getme')[0];
        var text=txt.textContent;
        console.log(text);
        console.log(pth);
        var n=text.length;
        while (txt.getSubStringLength(0,n+5)>290)
        {
            n--;
        }
        pth.textContent=text.slice(0,n)+'...'+text.slice(-3);
    });
    var open_shutter_path = function(angle){
        angle = angle==360 ? 360 : (angle||0)%360;
        angle-=90;
        var ex = Math.cos(angle/180*Math.PI)*500;
        var ey = Math.sin(angle/180*Math.PI)*500;
        var base = 'M0,0 L0,-500 A500,500 0 0,1 ';
        if (angle>90)
            base += '500,0 A500,500 0 0,1 ';
        if (angle>180)
            base += ' 0,500 A500,500 0 0,1 ';
        if (angle>270)
            base += '-500,0 A500 500 0 0,1 ';
        return base+ex+','+ey+' z';
    };
    var render_shutter = function(angle){
        angle = angle==720 ? 720 : angle%720;
        if(angle>360)
        {
            angle = 720-angle;
            document.getElementById('shutter').setAttribute('transform','rotate('+(360-angle)+')');
        }
        else
            document.getElementById('shutter').setAttribute('transform','');
        document.getElementById('shutter').setAttribute('d', open_shutter_path(angle));      
    };
    var render_spinner = function(angle){
        Array.prototype.forEach.call(document.querySelectorAll('.spinner'),function(spn){
            spn.setAttribute('transform','rotate('+angle+')');
        });
    };
    var shutter_pos=0;
    function cycle_shutter(){
        var old_step;
        var intv = setInterval(function(){
            shutter_pos+=2;
            render_shutter(shutter_pos);
            var step = 4-Math.trunc(shutter_pos/360);
            if (step!=old_step)
            {
                old_step=step;
                if(step>0)
                   ...