实现elementplus官网主题切换特效

概述

在使用elementplus文档的时候,如果留意的话,点击主题切换,会发现有一个鱼眼动画的奇幻,非常的炫酷如下:

实现效果

咱也实现一个差不多的

实现

ViewTransition API

实现上面的效果,先介绍下,ViewTransition,View Transitions APIViewTransition 接口表示视图过渡,并提供了在过渡到达不同状态时运行代码的功能(例如,准备运行动画,或动画完成),或跳过视图过渡。(mdn解释),View Transitions API 简化了复杂动画的实现,无需手动处理位置计算或动画控制,适合页面级的场景切换和动画增强。

具体代码事先

主要涉及到我们需要通过api提供的接口去做动画处理。

js 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
        :root {
            --color: #fff;
            background-color: var(--color);
        }

        :root.dark {
            --color: #008c8c;
        }

        ::view-transition-new(root),
        ::view-transition-old(root) {
            animation: none;
        }

        .dark::view-transition-old(root) {
            z-index: 100;
        }
    </style>
</head>

<body>
    <button id="operate-btn">切换主题</button>
    <script>
        const operateBtn = document.getElementById('operate-btn');

        function toggleTheme() {
            document.documentElement.classList.toggle('dark');
        }
        function operateFn(e) {
            const transition = document.startViewTransition(() => {
                toggleTheme()
            });
            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');

                const clipPathList = isDark ? clipPath.reverse() : clipPath
                document.documentElement.animate(
                    {
                        // 切换方向相反
                        clipPath: clipPathList
                    },
                    {
                        duration: 300,
                        // 如果要切换到暗色主题
                        pseudoElement: isDark
                            ? '::view-transition-old(root)'
                            : '::view-transition-new(root)'
                    }
                );
            });
        }
        operateBtn.addEventListener('click', operateFn);
    </script>
</body>

</html>
相关推荐
Jerry13 小时前
使用 Material 3 在 Compose 中设置主题
前端
chéng ௹13 小时前
uniapp 封装uni.showToast提示
前端·javascript·uni-app
tuokuac14 小时前
nginx配置前端请求转发到指定的后端ip
前端·tcp/ip·nginx
程序员爱钓鱼14 小时前
Go语言实战案例-开发一个Markdown转HTML工具
前端·后端·go
万少14 小时前
鸿蒙创新赛 HarmonyOS 6.0.0(20) 关键特性汇总
前端
还有多远.14 小时前
jsBridge接入流程
前端·javascript·vue.js·react.js
蝶恋舞者15 小时前
web 网页数据传输处理过程
前端
非凡ghost15 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
吃饭最爱15 小时前
html的基础知识
前端·html
我没想到原来他们都是一堆坏人15 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python