day34-Animated Countdown(动画倒计时)

这篇文章展示了一个50天学习项目中的第34天任务,即用HTML、CSS和JavaScript实现一个动画倒计时。代码包括HTML结构、CSS样式(用于背景、计数器和完成状态的动画)以及JavaScript部分,用于处理数字的显示和隐藏,以及重播功能。当倒计时结束后,会显示GO并提供一个重播按钮来重新开始计时。
摘要由CSDN通过智能技术生成

50 天学习 50 个项目 - HTMLCSS and JavaScript

day34-Animated Countdown(动画倒计时)

效果

在这里插入图片描述

index.html

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

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Animated Countdown</title>
    <link rel="stylesheet" href="style.css" />
</head>

<body>
    <!-- 计数器 -->
    <div class="counter">
        <div class="nums">
            <span class="in">3</span>
            <span>2</span>
            <span>1</span>
            <span>0</span>
        </div>
        <h4>准备</h4>
    </div>
    <!-- 完成 -->
    <div class="final">
        <h1>GO</h1>
        <button id="replay">重播</button>
    </div>
    <script src="script.js"></script>
</body>

</html>

style.css

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');

* {
    box-sizing: border-box;
}

body {
    background: url('https://source.unsplash.com/random/1000x600') no-repeat center/100% 100%;
    font-family: 'Roboto', sans-serif;
    margin: 0;
    height: 100vh;
    overflow: hidden;
}

/* 准备 */
h4 {
    font-size: 20px;
    margin: 5px;
}

/* 计数器 */
.counter {
    position: fixed;
    /* 居中 */
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
}

/* 隐藏计数器 */
.counter.hide {
    transform: translate(-50%, -50%) scale(0);
    animation: hide 0.2s ease-out;
}

/* 隐藏计数器动画 */
@keyframes hide {
    0% {
        transform: translate(-50%, -50%) scale(1);
    }

    100% {
        transform: translate(-50%, -50%) scale(0);
    }
}

/* 完成 默认隐藏 */
.final {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    text-align: center;
}

/* 完成 显示 */
.final.show {
    transform: translate(-50%, -50%) scale(1);
    animation: show 0.2s ease-out;
}

/* 完成 显示动画 */
@keyframes show {
    0% {
        transform: translate(-50%, -50%) scale(0);
    }

    30% {
        transform: translate(-50%, -50%) scale(1.4);
    }

    100% {
        transform: translate(-50%, -50%) scale(1);
    }
}

.nums {
    color: red;
    font-size: 50px;
    position: relative;
    overflow: hidden;
    width: 250px;
    height: 50px;
}

/* 数字 */
.nums span {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(120deg);
    /* 旋转中心为底部中心 */
    transform-origin: bottom center;
}

/* 显示数字 */
.nums span.in {
    transform: translate(-50%, -50%) rotate(0deg);
    animation: goIn 0.5s ease-in-out;
}

/* 隐藏数字 */
.nums span.out {
    animation: goOut 0.5s ease-in-out;
}

/* 显示数字 动画 */
@keyframes goIn {
    0% {
        transform: translate(-50%, -50%) rotate(120deg);
    }

    30% {
        transform: translate(-50%, -50%) rotate(-20deg);
    }

    60% {
        transform: translate(-50%, -50%) rotate(10deg);
    }

    100% {
        transform: translate(-50%, -50%) rotate(0deg);
    }
}

/* 隐藏数字 动画 */
@keyframes goOut {
    0% {
        transform: translate(-50%, -50%) rotate(0deg);
    }

    60% {
        transform: translate(-50%, -50%) rotate(20deg);
    }

    100% {
        transform: translate(-50%, -50%) rotate(-120deg);
    }
}

script.js

// 重点 position: fixed; transform animation keyframes   num.addEventListener('animationend'
// 1.获取元素节点 
const nums = document.querySelectorAll('.nums span') //数字
const counter = document.querySelector('.counter')  //计数器
const finalMessage = document.querySelector('.final') //完成
const replay = document.querySelector('#replay') //重播
// 执行动画
runAnimation()
// 初始化
function resetDOM() {
    // 计数器显示
    counter.classList.remove('hide')
    // 完成 隐藏
    finalMessage.classList.remove('show')
    // 全部数字的类为空
    nums.forEach((num) => {
        num.classList.value = ''
    })
    // 第一个数字显示
    nums[0].classList.add('in')
}
// 倒计时
function runAnimation() {
    nums.forEach((num, idx) => {
        const nextToLast = nums.length - 1
        // 添加了一个事件监听器,当动画结束时执行相应的回调函数。
        // 注意:一个数字有两个动画
        num.addEventListener('animationend', (e) => {
            // 前三个的数字 e.animationName 事件的动画名称
            if (e.animationName === 'goIn' && idx !== nextToLast) {
                // 隐藏
                console.log(idx);//0 1 2 
                num.classList.remove('in')
                num.classList.add('out')
            } else if (e.animationName === 'goOut' && num.nextElementSibling) {//前三个的数字
                console.log(idx);//0 1 2 
                num.nextElementSibling.classList.add('in')
            } else {//最后一个数字
                // 计数器隐藏
                counter.classList.add('hide')
                // 完成 显示
                finalMessage.classList.add('show')
            }
        })
    })
}
// 重播按钮 点击
replay.addEventListener('click', () => {
    // 初始化
    resetDOM()
    // 执行动画
    runAnimation()
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值