主题切换过渡切割效果

主题切换过渡切割效果

效果图

请添加图片描述

参考api View Transitions API
View Transitions API 提供了一种机制,可以在更新 DOM 内容的同时,轻松地创建不同 DOM 状态之间的动画过渡。同时还可以在单个步骤中更新 DOM 内容。

在这里插入图片描述

上代码

<!--
 * @Descripttion: 
 * @Author: 苍狼一啸八荒惊
 * @Date: 2024-09-03 14:16:43
 * @LastEditTime: 2024-09-04 14:06:25
 * @LastEditors: 夜空孤狼啸
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>主题切换</title>
    <style>
        :root {
    
    
            /* 亮色模式下的背景色 */
            --bg-color: #fff;
            --text-color: #232324;
            background-color: var(--bg-color);
        }

        :root.dark {
    
    
            /* 暗色模式下的背景色 */
            --text-color: #dbdbdf;
            --bg-color: #000;
        }

        .dark::view-transition-old(root) {
    
    
            z-index: 100;
        }

        ::view-transition-new(root),
        ::view-transition-old(root) {
    
    
            /* 关闭默认动画,否则影响自定义动画的执行 */
            animation: none;
        }

        body {
    
    
            color: var(--text-color);
        }
    </style>
</head>

<body>
    <button id="btn">切换主题</button>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <h1>点击按钮时切换主题</h1>
    <script>
        const btn = document.getElementById('btn')
        // 点击按钮时切换主题
        btn.addEventListener('click', (e) => {
    
    
            // 获取到 transition API 实例
            const transition = document.startViewTransition(() => {
    
    
                document.documentElement.classList.toggle('dark')
            })

            // 在 transition.ready 的 Promise 完成后,执行自定义动画
            transition.ready.then(() => {
    
    
                // 由于我们要从鼠标点击的位置开始做动画,所以我们需要先获取到鼠标的位置
                const {
    
     clientX, clientY } = e

                // 计算半径,以鼠标点击的位置为圆心,到四个角的距离中最大的那个作为半径
                const radius = Math.hypot(
                    Math.max(clientX, innerWidth - clientX),
                    Math.max(clientY, innerHeight - clientY)
                )
                const clipPath = [
                    `circle(0% at ${
      
      clientX}px ${
      
      clientY}px)`,
                    `circle(${
      
      radius}px at ${
      
      clientX}px ${
      
      clientY}px)`
                ]
                const isDark = document.documentElement.classList.contains('dark')
                console.log(isDark)
                // 自定义动画
                document.documentElement.animate(
                    {
    
    
                        // 如果要切换到暗色主题,我们在过渡的时候从半径 100% 的圆开始,到 0% 的圆结束
                        clipPath: isDark ? clipPath.reverse() : clipPath
                    },
                    {
    
    
                        duration: 500,
                        // 如果要切换到暗色主题,我们应该裁剪 view-transition-old(root) 的内容
                        pseudoElement: isDark
                            ? '::view-transition-old(root)'
                            : '::view-transition-new(root)'
                    }
                )
            })
        })



    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/qq_43940789/article/details/141892368