Search code examples
javascripthtmlcssanimationloading

How to create a CSS spinning loading animation?


I want to create a css (or JS) loading animation depicted in this image:

enter image description here

There should be a container rectangle which has a class. Then some css should be applied to that rectangle so that there is some overlay. First it is all black with 50% transparency. Then over time, the black reduces as it spins clockwise, until there is no more black again. If I give it a value of 100, it should be all black, if I give it 0, it should have no black, and just show the underlying image completely.

Anyone know any tutorial or how to create this?


Solution

  • I figured it out using canvas.

    var canvas = document.getElementById('loading_animation');
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#00000088';
    
    var final = [];
    var list1 = [
        [Math.floor(canvas.width / 2), 0],
        [Math.floor(canvas.width / 2), Math.floor(canvas.height / 2)]
    ];
    var list2 = [
        [canvas.width - 1, 0],
        [canvas.width - 1, canvas.height - 1],
        [0, canvas.height - 1],
        [0, 0]
    ];
    var last = [Math.floor(canvas.width / 2), 0];
    
    for (var x = Math.floor(canvas.width / 2); x < canvas.width; x += 1) {
        var path = list1.concat([[x, 0]]).concat(list2).concat([last]);
        final.push(path);
    }
    list2.shift();
    for (var y = 1; y < canvas.height; y += 1) {
        var path = list1.concat([[canvas.width - 1, y]]).concat(list2).concat([last]);
        final.push(path);
    }
    list2.shift();
    for (var x = canvas.width - 2; x >= 0; x -= 1) {
        var path = list1.concat([[x, canvas.height - 1]]).concat(list2).concat([last]);
        final.push(path);
    }
    list2.shift();
    for (var y = canvas.height - 2; y >= 0; y -= 1) {
        var path = list1.concat([[0, y]]).concat(list2).concat([last]);
        final.push(path);
    }
    list2.shift();
    for (var x = 1; x < Math.floor(canvas.width / 2); x += 1) {
        var path = list1.concat([[x, 0]]).concat(list2).concat([last]);
        final.push(path);
    }
    function RenderAnimation() {
        var path = final.shift();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.beginPath();
        ctx.moveTo(path[0][0], path[0][1]);
        for (let i = 1; i < path.length; i++) {
            ctx.lineTo(path[i][0], path[i][1]);
        }
        ctx.closePath();
        ctx.fill();
        if (final.length > 0) {
            window.requestAnimationFrame(RenderAnimation);
        } else {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        }
    }
    
    RenderAnimation();
        <!DOCTYPE html>
        <html>
        
        <head>
            <title>Title of the document</title>
            <style>
                canvas {
                    background-image: url('https://media.wired.com/photos/5d09594a62bcb0c9752779d9/125:94/w_1994,h_1500,c_limit/Transpo_G70_TA-518126.jpg');
                    background-size: 100% 100%;
                    background-repeat: no-repeat;
                }
            </style>
        </head>
        
        <body>
            <canvas id="loading_animation" width="300px" height="200px"></canvas>
        </body>
        
        </html>