实现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>
相关推荐
风止何安啊17 分钟前
收到字节的短信:Trae SOLO上线了?尝尝鲜,浅浅做个音乐播放器
前端·html·trae
抱琴_24 分钟前
大屏性能优化终极方案:请求合并+智能缓存双剑合璧
前端·javascript
用户4639897543224 分钟前
Harmony os——长时任务(Continuous Task,ArkTS)
前端
fruge25 分钟前
低版本浏览器兼容方案:IE11 适配 ES6 语法与 CSS 新特性
前端·css·es6
颜酱42 分钟前
开发工具链-构建、测试、代码质量校验常用包的比较
前端·javascript·node.js
颜酱1 小时前
package.json 配置指南
前端·javascript·node.js
todoitbo1 小时前
基于 DevUI MateChat 搭建前端编程学习智能助手:从痛点到解决方案
前端·学习·ai·状态模式·devui·matechat
oden2 小时前
SEO听不懂?看完这篇你明天就能优化网站了
前端
IT_陈寒2 小时前
React性能优化:这5个Hooks技巧让我减少了40%的重新渲染
前端·人工智能·后端
Sunhen_Qiletian2 小时前
《Python开发之语言基础》第六集:操作文件
前端·数据库·python