Vue3 + CSS: 实现扩散渐变动画

JavaScript系列文章



前言

本文将简单介绍Vue3结合CSS,实现扩散渐变动画特效。


一、项目演示

在这里插入图片描述

二、扩散渐变动画

2.1 工具类封装

// 暗黑主题切换
export const toggleTheme = event => {
  document.documentElement.classList.add('animate')
  setTimeout(() => {
    document.documentElement.classList.toggle('active')
    toggleTheme(event)
  }, 150)

  setTimeout(() => document.documentElement.classList.remove('animate'), 300)

  /**
   * 切换主题色,扩散渐变动画
   *
   * @param {MouseEvent} event 点击事件
   */
  function toggleTheme(event) {
    const willDark = !isDark()
    // 浏览器新特性不支持 或者 开启了动画减弱
    if (!document.startViewTransition || isReducedMotion()) {
      toggleDark()
      return
    }

    const transition = document.startViewTransition(() => {
      toggleDark()
    })

    // 传入点击事件,从点击处开始扩散。否则,从右上角开始扩散
    const x = event?.clientX ?? window.innerWidth
    const y = event?.clientY ?? 0

    const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y))
    void transition.ready.then(() => {
      const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`]
      document.documentElement.animate(
        {
          clipPath: willDark ? clipPath : [...clipPath].reverse()
        },
        {
          duration: 500,
          easing: 'ease-in',
          pseudoElement: willDark ? '::view-transition-new(root)' : '::view-transition-old(root)'
        }
      )
    })
  }
  
  /**
   * 切换主题色,html标签切换dark类
   */
  function toggleDark() {
    store.dispatch('login/useDark')

    document.documentElement.classList.toggle('dark')
  }

  /**
   * 检测用户的系统是否被开启了动画减弱功能
   * @link https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media/prefers-reduced-motion
   */
  function isReducedMotion() {
    return window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true
  }

  /**
   * 当前主题色是否是暗色
   */
  function isDark() {
    return document.documentElement.classList.contains('dark')
  }
}

2.2 视图层编写

2.2.1 点击事件

<div class="toolbar-item" @click="toggleTheme">
<div :class="['iconfont', $store.getters.isDark ? 'icon-yewan' : 'icon-qingtian']"></div></div>

2.2.2 函数引用

<script setup>
import { toggleTheme, toggleFullScreen } from '@/util/util'
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值