見出し画像

オサレなカーソル

index.html

<!DOCTYPE html class="my-2 rounded-full h-10 w-[16rem] px-4">
<html lang="jp">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.css" />

    <title>カーソル1</title>
</head>

<style>
    html,
    body {
        margin: 0;
        padding: 0;
    }
    
    body {
        width: 100vw;
        height: 100vh;
        background: black;
        overflow: hidden;
    }
    
    @property --hue {
        syntax: "<number>";
        initial-value: 0;
        inherits: true;
    }
    
    @property --scale {
        syntax: "<number>";
        initial-value: 0;
        inherits: true;
    }
    
    .drop {
        position: absolute;
        --_x: calc(var(--x) * 1px);
        --_y: calc(var(--y) * 1px);
        --start1: 0;
        --stop1: 360;
        --start2: 180;
        --stop2: 250;
        --_hue: calc( ( (calc(var(--hue) - var(--start1))) / calc(var(--stop1) - var(--start1))) * calc(var(--stop2) - var(--start2)) + var(--start2));
        --_scale: calc(1 + calc(var(--scale) * var(--elevation)));
        left: var(--_x, 50vh);
        top: var(--_y, 50vw);
        width: 50px;
        height: 50px;
        border-radius: 50%;
        filter: blur(1px);
        box-shadow: 2px 1px 17px 0px hsla(var(--_hue, 100) 100% 50% / 50%);
        transform: translate(-50%, -50%) scale(var(--_scale, 1));
    }
</style>

<body>
    <div class="firework"></div>
    <div class="firework"></div>
    <div class="firework"></div>

    <script>
        let then = performance.now();
        let hue = 0;
        let x;
        let y;

        const growKeyframes = (hue) => [{
            opacity: 0,
            "--hue": 0,
            "--scale": 0,
        }, {
            opacity: 0.75,
        }, {
            opacity: 0.75,
            "--hue": hue,
            "--scale": 4,
        }, {
            opacity: 0,
            "--hue": hue,
            "--scale": 1,
        }, ];

        const growTiming = {
            duration: 3000,
            iterations: 1,
            easing: "ease-out",
        };

        const addElement = ({
            x,
            y,
            hue,
            elevation
        }) => {
            const drop = document.body.appendChild(document.createElement("div"));

            drop.classList.add("drop");

            if (x && y) {
                drop.style.setProperty("--x", x);
                drop.style.setProperty("--y", y);
                drop.style.setProperty("--elevation", elevation);
            }

            drop.style.setProperty("--elevation", elevation);

            drop
                .animate(growKeyframes(hue), growTiming)
                .finished.then((e) => drop.remove());
        };

        const loop = () => {
            const now = performance.now();
            const delta = now - then;
            const {
                innerHeight
            } = window;
            const elevation = 1 - y / innerHeight;

            if (delta > 50) {
                then = now;
                hue += 1;

                addElement({
                    x,
                    y,
                    hue,
                    elevation,
                });
            }

            requestAnimationFrame(loop);
        };

        document.body.addEventListener("pointermove", (e) => {
            x = e.clientX;
            y = e.clientY;
        });

        loop();
    </script>
</body>

</html>

index.html

いいなと思ったら応援しよう!