Make theme switching cinematic

主题切换动画库:新主题以 13 种形状揭开旧主题,而不是生硬跳变。支持 React / Vue / Next.js / Nuxt;受控模式无缝接入 next-themes / @nuxtjs/color-mode,多实例与跨标签页状态自动同步。
Features

小而完整的动画层

约 95% 代码与框架无关,两个薄适配层覆盖 React 与 Vue 生态。

跨框架

一套核心,四种用法:React / Vue composable、Next.js 受控示例、Nuxt 模块自动导入。

React 18+Vue 3+Next.jsNuxt 3+

13 种动画

圆形扩散 / 收起 / 模糊、四向擦除、几何形状扩散,起收点跟随点击位置。

CIRCLEREVERTBLURSTAR

受控模式

不独占主题状态:next-themes 与 @nuxtjs/color-mode 用户直接接入,300ms 未同步自动直切。

next-themes@nuxtjs/color-mode

多实例同步

同页多个实例的 isDark 以 html class 为事实源镜像,其它标签页经 storage 事件同步。

observeThemeClassfinished

优雅降级

不支持 View Transitions、SSR、prefers-reduced-motion:跳过动画,状态永远正确。

SSR 安全reduced-motion
Quick Start

三行代码接入

四个入口,同一套 API。受控模式接入 next-themes / @nuxtjs/color-mode 的完整示例见 GitHub README

npm install theme-switch-animation
'use client'
import { ThemeAnimationType, useThemeAnimation } from 'theme-switch-animation/react'

export function ThemeToggle() {
  // 非受控:库管理 localStorage + <html> class
  // 多实例 / 跨标签页的 isDark 自动同步(以 html class 为事实源)
  const { ref, toggleTheme, isDark, finished } = useThemeAnimation({
    animationType: ThemeAnimationType.CIRCLE,
    duration: 750,
  })

  return (
    <button ref={ref} onClick={toggleTheme}>
      {isDark ? '🌙' : '☀️'}
      {/* finished:本次动画结束 Promise,可 await 做动画期间禁用 */}
    </button>
  )
}

FAQ