JavaScript Moon Orbit

How to Create a Moon Orbit Around Earth with Trail Effect Vanilla JavaScript

html

<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <script src="./main.js" defer></script>
    <title>Orbit Moon to Earth</title>
</head>

<body>
    <div id="line">
        <div class="moon"></div>
        <div class="planet"></div>
    </div>
</body>

</html>

css

body {
    width: 100%;
    height: 100vh;
    margin: 0;
    box-sizing: border-box;
    overflow: hidden;
    background-color: #000;
    display: flex;
    justify-content: center;
    align-items: center;
}

#line {
    width: 300px;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    border-radius: 100%;
    /* border: 1px dashed #FFFFFF50; */

    & .moon {
        width: 30px;
        height: 30px;
        border-radius: 100%;
        position: initial;
        background-size: cover;
        background-image: url("https://sciencezone.net/wp-content/uploads/2019/09/moon.jpg");
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        animation: orbit 5s linear infinite;
    }

    & .planet {
        width: 60px;
        height: 60px;
        border-radius: 100%;
        position: absolute;
        background-size: cover;
        background-image: url("https://www.publicdomainpictures.net/pictures/220000/velka/planet-1494403454Zmz.jpg");
    }
}

.trail {
    width: 3px;
    height: 3px;
    background-color: rgba(255, 255, 255, 0.7);
    position: absolute;
    border-radius: 50%;
    transition: opacity 1s ease-out;
    z-index: -100;
}

@keyframes orbit {
    0% {
        transform: rotate(0deg) translateX(150px) rotate(0deg);
    }

    100% {
        transform: rotate(360deg) translateX(150px) rotate(-360deg);
    }
}

javascript

const line = document.querySelector('#line');
const moon = document.querySelector('.moon');

function createTrail() {
    const trail = document.createElement('div');
    trail.classList.add('trail');

    const lineRect = line.getBoundingClientRect();
    const moonRect = moon.getBoundingClientRect();

    trail.style.left = `${moonRect.left - lineRect.left + moonRect.width / 2}px`;
    trail.style.top = `${moonRect.top - lineRect.top + moonRect.height / 2}px`;

    line.appendChild(trail);

    setTimeout(() => {
        trail.style.opacity = '0';
        setTimeout(() => {
            trail.remove();
        }, 1000);
    }, 500);
}

setInterval(createTrail, 100);