Html转场动画/无缝页面转换

发布于:2024-12-07 ⋅ 阅读:(102) ⋅ 点赞:(0)

实现上面那种动画无缝转场,今天刷B站的时候发现的,感觉这种的动画好炫酷,而且实现起来也并不复杂,于是自己手写了一份(虽然写的很烂,但还是辛苦我了)

大致原理

通过观察地址栏,可以发现这种动画其实就是点击跳转链接的时候并不是立即跳转,而是等待动画结束的时候再跳转,其次,当进入新页面的时候先保留住动画,再按相反的方向执行这个动画就OK了。

所以大概流程就是:

  1. 点击链接 -> 定时器动画 ->跳转
  2. 当页面加载时->触发动画 -> 正常展示页面即可

这种效果按理按说应该做成一种通用型的结构,但是我只是做着玩玩,所以怎么简单怎么来了

对于页面结构,动画需要铺满整个屏幕,可以分成5个部分(自己定义,改改CSS样式就行),每个部分分成上下两条,每一个部分的动画都是同步的

第一个文件

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home | index</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .title {
            display: flex;
            position: relative;
            width: 100%;
            justify-content: space-between;
        }

        .left {
            color: black;
            font-weight: 700;
            margin-left: 40px;
            margin-top: 20px;
        }

        .right {
            margin-right: 40px;
            margin-top: 20px;
        }

        ul {
            list-style: none;
            display: flex;
            width: 200px;
            justify-content: space-around;
            color: black;
            font-weight: 700;
        }

        .text {
            font-size: 200px;
            text-align: center;
            transform: translateY(50%);
            top: -50%;
        }

        .animation {
            position: fixed;
            z-index: 1;
            width: 100%;
            height: 100%;
            /* display: none; */

            /* opacity: 0; */

        }

        .animation-ul {
            width: 100%;
            height: 100%;


        }

        .animation-ul li {
            width: 20%;
            height: 100%;
            /* border: 1px solid black; */

        }

        .top,
        .bottom {
            width: 100%;
            height: 50%;
            background-color: #746CF2;
            transition: all 1.5s ease;

            /* border: 1px solid black; */
        }

        .top {
            transform: translateY(0);
        }

        .bottom {
            transform: translateY(0);
        }

        #Home {
            cursor: pointer;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <!-- #746CF2 -->
    <div class="animation">
        <ul class="animation-ul">
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
        </ul>
    </div>

    <div class="title">
        <div class="left">
            WangKaiFu
        </div>
        <div class="right">
            <ul>
                <li id="about">Home</li>
                <li id="Home">About</li>
                <li>Contact</li>
            </ul>
        </div>
    </div>
    <div class="text">
        INDEX
    </div>

    <script>
        window.onload = function () {
            const list = document.querySelectorAll(".animation-ul li");


            setTimeout(() => {
                for (let i = 0; i < list.length; i++) {
                    setTimeout(() => {
                        list[i].querySelector(".top").style.transform = "translateY(-100%)";
                        list[i].querySelector(".bottom").style.transform = "translateY(100%)";
                        console.log(list[i].querySelector(".top"))
                    }, 200 * i)
                }
            }, 0)
            setTimeout(() => {
                document.querySelector(".animation").style.display = "none";

            }, 2100)
        }

        let home = document.querySelector("#Home");
        const list = document.querySelectorAll(".animation-ul li");
        console.log(list)
        home.addEventListener("click", () => {
            document.querySelector(".animation").style.display = "block";

            setTimeout(() => {
                setTimeout(() => {
                    location.href = "./about.html"
                }, 2000)
                for (let i = 0; i < list.length; i++) {
                    setTimeout(() => {
                        list[i].querySelector(".top").style.transform = "translateY(0)";
                        list[i].querySelector(".bottom").style.transform = "translateY(0)";
                        console.log(list[i].querySelector(".top"))
                    }, 200 * i)
                }


            }, 0)

        })
    </script>
</body>

</html>

 第二个文件

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home | About</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .title {
            display: flex;
            position: relative;
            width: 100%;
            justify-content: space-between;
        }

        .left {
            color: black;
            font-weight: 700;
            margin-left: 40px;
            margin-top: 20px;
        }

        .right {
            margin-right: 40px;
            margin-top: 20px;
        }

        ul {
            list-style: none;
            display: flex;
            width: 200px;
            justify-content: space-around;
            color: black;
            font-weight: 700;
        }

        .text {
            font-size: 200px;
            text-align: center;
            transform: translateY(50%);
            top: -50%;
        }

        .animation {
            position: fixed;
            z-index: 1;
            width: 100%;
            height: 100%;
            /* display: none; */

            /* opacity: 0; */

        }

        .animation-ul {
            width: 100%;
            height: 100%;


        }

        .animation-ul li {
            width: 20%;
            height: 100%;
            /* border: 1px solid black; */

        }

        .top,
        .bottom {
            width: 100%;
            height: 50%;
            background-color: #746CF2;
            transition: all 1.5s ease;

            /* border: 1px solid black; */
        }

        .top {
            transform: translateY(0);
        }

        .bottom {
            transform: translateY(0);
        }

        #Home {
            cursor: pointer;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <!-- #746CF2 -->
    <div class="animation">
        <ul class="animation-ul">
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
            <li>
                <div class="top"></div>
                <div class="bottom"></div>
            </li>
        </ul>
    </div>
    <div class="title">
        <div class="left">
            WangKaiFu
        </div>
        <div class="right">
            <ul>
                <li id="Home">Home</li>
                <li id="About">About</li>
                <li>Contact</li>
            </ul>
        </div>
    </div>
    <div class="text">
        About
    </div>
    <script>
        window.onload = function () {
            const list = document.querySelectorAll(".animation-ul li");


            setTimeout(() => {
                for (let i = 0; i < list.length; i++) {
                    setTimeout(() => {
                        list[i].querySelector(".top").style.transform = "translateY(-100%)";
                        list[i].querySelector(".bottom").style.transform = "translateY(100%)";
                        console.log(list[i].querySelector(".top"))
                    }, 200 * i)
                }
            }, 0)
            setTimeout(() => {
                document.querySelector(".animation").style.display = "none";

            }, 2200)
        }
        let home = document.querySelector("#Home");
        const list = document.querySelectorAll(".animation-ul li");
        console.log(list)
        home.addEventListener("click", () => {
            document.querySelector(".animation").style.display = "block";

            setTimeout(() => {
                setTimeout(() => {
                    location.href = "./index.html"
                }, 2000)
                for (let i = 0; i < list.length; i++) {
                    setTimeout(() => {
                        list[i].querySelector(".top").style.transform = "translateY(0)";
                        list[i].querySelector(".bottom").style.transform = "translateY(0)";
                        console.log(list[i].querySelector(".top"))
                    }, 200 * i)
                }


            }, 0)

        })
    </script>
</body>

</html>

在做动画的时候遇到了什么问题呢?

第一个,最开始的时候需要将整个动画div隐藏(display:none),当点击按钮的时候再显示,并执行动画,通过JS可以很轻松实现,但是观察效果的时候发现整个动画完全不见了,这可能是js有类似重排序指令?或者同步执行代码过快,当动画已经开始位移的时候页面还是隐藏状态,然后突然想起来了setTimeout(0)这个感觉没啥用的定时器,因为js会先执行同步代码,然后再执行异步代码,隐藏将动画放入到setTimeout(0)就完美解决了顺序问题(看来面试题还是有用的)

第二个,还是定时器的问题,因为要控制每一个动画div的分开移动,我在for遍历的时候再每个定时器中添加了setTimeout(200)想要在每次执行完一个动画后暂停一段时间,但是最后的效果是全部动画整体移动(在定时器中的输出语句也是同步全部输出),我原本以为每个定时器都会在上一个循环结束后才会执行,但是循环里全部的定时器都是同步执行的,搞蒙了一段时间,最后感觉是js对循环有优化,不过这个问题也很好解决,每个定时器都乘上一个倍数就可以分开了