CSS 打字效果和JS监听元素即将进入视口后再加载


CSS 打字效果和JS监听动画元素即将进入视口后再加载


截图

主要是JS监听动画元素即将进入视口后再加载


<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="format-detection" content="telephone=no">

    <style>
        .ooo {
            font-size: 30px;
            width: 14em;
            height: 1.25em;
            white-space: nowrap;
            border-right: 3px solid transparent;
            font-family: 楷体, Consolas, Monaco;
            font-weight: 800;
            word-break: break-all;
            overflow: hidden;
        }

        .typing {
            font-size: 30px;
            width: 14em;
            height: 1.25em;
            white-space: nowrap;
            border-right: 3px solid transparent;
            animation: typing 3s forwards steps(26, end), blink-caret .75s forwards step-end;
            animation-direction: alternate;
            font-family: 楷体, Consolas, Monaco;
            font-weight: 800;
            word-break: break-all;
            overflow: hidden;

        }

        .ooo {
            font-size: 30px;
            width: 14em;
            height: 1.25em;
            white-space: nowrap;
            border-right: 3px solid transparent;
            font-family: 楷体, Consolas, Monaco;
            font-weight: 800;
            word-break: break-all;
            overflow: hidden;
        }

        /* 打印效果 */
        @keyframes typing {
            from {
                width: 0;
            }

            to {
                width: 14em;
            }
        }

        /* 光标闪啊闪 */
        @keyframes blink-caret {

            from,
            to {
                border-color: transparent;
            }

            50% {
                border-color: currentColor;
            }
        }

        .dazi {
            background-color: #fff;
            border: 3px solid #000;
            padding: 5px 0;
            margin: 5px 0;
        }

        .kuyun {
            display: flex;
            height: 4em;
            width: 100%;
            background-color: #000;
            overflow: hidden;
            font-family: sans-serif;
        }

        .kuyun h1 {
            position: relative;
            margin: auto;
            font-size: 30px;
            font-weight: bold;
            color: #fff;
            letter-spacing: 0.02em;
            text-transform: uppercase;
            text-shadow: 0 0 10px blue;
            user-select: none;
            white-space: nowrap;
            filter: blur(0.007em);
            animation: shake 2.5s .2s linear forwards;
        }

        .kuyun h1 span {
            position: absolute;
            top: 0;
            left: 0;
            transform: translate(-50%, -50%);
            clip-path: polygon(10% 0%, 44% 0%, 70% 100%, 55% 100%);
        }

        .kuyun h1::before,
        .kuyun h1::after {
            content: attr(data-text);
            position: absolute;
            top: 0;
            left: 0;
        }

        .kuyun h1::before {
            animation: crack1 2.5s linear forwards;
            clip-path: polygon(0% 0%, 10% 0%, 55% 100%, 0% 100%);
        }

        .kuyun h1::after {
            animation: crack2 2.5s linear forwards;
            clip-path: polygon(44% 0%, 100% 0%, 100% 100%, 70% 100%);
        }

        @keyframes shake {

            5%,
            15%,
            25%,
            35%,
            55%,
            65%,
            75%,
            95% {
                filter: blur(0.018em);
                transform: translateY(0.018em) rotate(0deg);
            }

            10%,
            30%,
            40%,
            50%,
            70%,
            80%,
            90% {
                filter: blur(0.01em);
                transform: translateY(-0.018em) rotate(0deg);
            }

            20%,
            60% {
                filter: blur(0.03em);
                transform: translate(-0.018em, 0.018em) rotate(0deg);
            }

            45%,
            85% {
                filter: blur(0.03em);
                transform: translate(0.018em, -0.018em) rotate(0deg);
            }

            100% {
                filter: blur(0.007em);
                transform: translate(0) rotate(-0.5deg);
            }
        }

        @keyframes crack1 {

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

            100% {
                transform: translate(-51%, -48%);
            }
        }

        @keyframes crack2 {

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

            100% {
                transform: translate(-49%, -53%);
            }
        }
    </style>

</head>

<body>


    <div class="dazi">
        <p class="typing ooo">还是打飞机烤红薯的</p>
    </div>




    <!-- 使用HTML5的新属性:数据属性:data-, -->
    <div id="1x1m" data-animation="kuyun" class="waiting-for-add">
        <h1 data-text="还是打飞机烤红薯的"><span>还是打飞机烤红薯的</span></h1>
    </div>

    <script>
    	// 处理typing动画暂停5s
        var scrollTip = document.querySelector('.typing');
        scrollTip.classList.add('typing');
        scrollTip.addEventListener('animationend', function () {
            scrollTip.classList.remove('typing');
            setTimeout(function () {
                scrollTip.classList.add('typing');
            }, 5000)
        })
    </script>

	
    <script>
    	// 开始进入视口的动画
        // 当元素进入视图时触发的回调函数
        const handleIntersection = (entries, observer) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const animationClassName = entry.target.getAttribute('data-animation');
                    entry.target.classList.add(animationClassName); // 添加对应的动画
                    observer.unobserve(entry.target); // 元素一旦进入视图并开始动画,停止观察它
                }
            });
        };

        // 配置Intersection Observer
        const options = {
            root: null,         // 使用视口作为根
            rootMargin: '0px',  // 无边距
            threshold: 0.1      // 当元素至少有10%可见时触发
        };

        const observer = new IntersectionObserver(handleIntersection, options);

        // 观察所有希望在进入视图时开始动画的元素
        const elements = document.querySelectorAll('.waiting-for-add');
        elements.forEach(el => {
            observer.observe(el);
        });
    </script>

</body>
</html>

文章作者: Alan Work
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alan Work !
  目录