CSS-анимированная кнопка и настраиваемый счетчик из div

Я знаю, что мог бы использовать <meter> элемент, но я хотел попробовать реализовать с нуля. Позиции немного хакерские, и я попытался сделать его отзывчивым, но в итоге использовал px так или иначе. Я хотел бы получить совет о том, когда и как использовать калибровочные единицы, если это возможно. Спасибо!

PS Пожалуйста, не обращайте внимания на дурацкие имена переменных. Я обычно использую хорошие имена, но это было как бы взломано вместе: D

HTML:

<head>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Titillium+Web:wght@200&display=swap" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<div class="wrapper">
        <div class="meter-container">
            <span>Sci-fi juice meter</span>
            <div class="energy-meter">
                <div class="energy stable-juice-anim"></div>
            </div>
        </div>
        
        <div class="animated-button">
            <span>Click</span>
        </div>
    </div>

CSS:

body {
    display: flex;
    height: 100vh;
    width: 100vw;
    margin: 0;
}

video {
    min-height: 300px;
    min-width: 300px;
    max-height: 600px;
    max-height: width: 600px;
}

.dark {
    background-color: rgb(10, 10, 10) !important; 
}

.wrapper {
    display: flex;
    height: 100%;
    width: 100%;
    align-items: center;
    justify-content: center;
    background-color: rgba(60, 60, 60, 0.2);
    overflow: hidden;
}

.meter-container {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    position: fixed;
    top: 5vh;
    left: 70vw;
    height: 200px;
    width: 150px;

}

.meter-container span {
    flex: 0.1;
    font-size: 0.7em;
}

.energy-meter {
    display: flex;
    align-items: flex-end;
    flex: 1;
    border: 2px solid;
    border-radius: 5.4%;
    height: 80%;
    width: 20%;
    overflow: hidden;
}


.energy {
    position: relative;
    background-color: rgb(50, 255, 50);
    margin-bottom: -50px;
    height: 50%;
    width: 100%;
}

.animated-button {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100px;
    width: 100px;
    background-color: white;
    box-shadow: 0px 0px 5px 10px rgba(60, 60, 60, 0.2);
    border-radius: 50%;
}

.animated-button span {
    font-family: "Titillium Web";
    font-size: 2em;
    cursor: default;
}

.button-anim {
    animation: shrink, shake, implode, explode;
    animation-duration: 1s, 0.2s, 1s, 2s;
    animation-delay: 0s, 0s, 1s, 2s;
    animation-iteration-count: 1, 5, 1, 1;
    animation-fill-mode: forwards;
}

.fade-anim {
    animation: disappear 1s;
    animation-fill-mode: forwards;
}

.stable-juice-anim {
    animation: energy-stable 7s infinite;
}

.overflowing-juice-anim {
    animation: energy-overflow 3s;
}

@keyframes energy-stable {
    0% {
        transform: scaleY(1);
    }
    25% {
        transform: scaleY(1.1);
    }
    50% {
        transform: scaleY(1);
    }
    75% {
        transform: scaleY(0.9);
    }
    100% {
        transform: scaleY(1);
    }
}

@keyframes energy-overflow {
    from {
        transform: scaleY(1);
    }
    to {
        transform: scaleY(4.6);
        background-color: rgb(255, 0, 0);
    }
}
@keyframes disappear {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
        display: none;
    }
}

@keyframes shrink {
    from {
        transform: scale(1);
    }

    to {
        transform: scale(0.5);
        background-color: rgb(10, 10, 10);
        box-shadow: none;
    }
}

@keyframes shake {
    0% {
        transform: translate(-2.5%, -2.5%), scale(0.5);
    }

    20% {
        transform: translate(5%, 5%) scale(0.5);
    }

    40% {
        transform: translate(-2.5%, -2.5%) scale(0.5);
    }

    50% {
        transform: translate(2.5%, -2.5%) scale(0.5);
    }

    60% {
        transform: translate(-5%, 5%), scale(0.5);
    }

    80% {
        transform: translate(2.5%, -2.5%) scale(0.5);
    }
    100% {
        transform: translate(-2.5%, -2.5%) scale(0.5);
    }
}

@keyframes implode {
    from {
        transform: scale(0.5);
    }

    to {
        transform: scale(0);
    }
}

@keyframes explode {
    from {
        transform: scale(0);
    }

    to {
        transform: scale(200);
        background-color: rgb(10, 10, 10);
    }
}

JS:

"use strict";
let buttonElement = document.getElementsByClassName("animated-button")[0];
let wrapperElement = document.getElementsByClassName("wrapper")[0];
let energyElement = document.getElementsByClassName("energy")[0];
let energyMeterContainerElement = document.getElementsByClassName("meter-container")[0];

buttonElement.onclick = (e) => {
    let buttonTextElement = buttonElement.firstElementChild;
    buttonTextElement.classList.add("fade-anim");
    setTimeout(() => {
        buttonElement.classList.add("button-anim");
        energyElement.classList.remove("stable-juice-anim");
        energyElement.classList.add("overflowing-juice-anim");
        setTimeout(() => {
            wrapperElement.classList.add("dark");
            let lolElement = document.createElement("video");
            lolElement.src = "https://ak.picdn.net/shutterstock/videos/1054729307/preview/stock-footage-aerial-view-of-the-sunsets-over-sea-beautiful-sea-waves-pink-sand-and-amazing-sea-summer-sunset.mp4";
            lolElement.setAttribute("autoplay", "");
            lolElement.setAttribute("muted", "");
            wrapperElement.appendChild(lolElement);
            wrapperElement.removeChild(energyMeterContainerElement);
        }, 3000);
        setTimeout(() => wrapperElement.removeChild(buttonElement), 4000);
    }, 1000);
    buttonElement.onclick = undefined;
}
```

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *