tsParticles themes 插件:预定义主题、自动深色模式与运行时切换全指南
2026/9/18 9:11:56 网站建设 项目流程

tsParticles themes 插件:预定义主题、自动深色模式与运行时切换全指南

【免费下载链接】tsparticlestsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.项目地址: https://gitcode.com/GitHub_Trending/ts/tsparticles

导读

themes是 tsParticles 官方插件之一,它允许你在初始化配置中预定义多套「主题」(每套主题包含独立的粒子选项覆盖),并支持按名称在运行时一键切换、跟随操作系统prefers-color-scheme自动应用深色/浅色主题。读完本文,你将掌握ThemeThemeDefault的全部配置项、ThemeMode枚举语义、主题加载的底层调用链,并能在自己的项目中写出可运行的深色/浅色主题切换方案。

本文对应的官方文档为 markdown/Options/Plugins/Themes.md,所有源码引用均来自仓库中的 plugins/themes 与 engine 模块。

一、插件定位:什么是 themes 插件

在 tsParticles 中,插件(plugin)负责扩展引擎的能力。themes插件的核心作用是:让同一份粒子实例可以拥有多套可切换的完整配置。这与responsive(响应式)按屏幕宽度切换不同,主题是按「名称」或「系统外观(深色/浅色)」切换。

  • 插件 ID 为theme,由ThemesPlugin类声明(见 plugins/themes/src/ThemesPlugin.ts);
  • 插件通过 plugins/themes/src/index.ts 中的loadThemesPlugin(engine)注册到引擎的插件管理器,使用前必须先加载该插件;
  • 配置入口为themes数组,数组中的每个元素都是一个完整的Theme对象。

从源码结构看,themes插件由四个部分组成:选项类(ThemeThemeDefault)、选项接口(IThemeIThemeDefault)、模式枚举(ThemeMode)以及插件实例(负责运行时监听与切换)。

二、Theme 核心配置属性

每个主题对象(ITheme/Theme类)包含三个属性,定义在 plugins/themes/src/Options/Classes/Theme.ts 与 plugins/themes/src/Options/Interfaces/ITheme.ts 中:

属性类型默认值说明
namestring""主题名称,运行时通过该名称切换主题
defaultThemeDefault见下文默认对象用于设置「默认主题」行为的子对象
optionsISourceOptions \| undefinedundefined该主题将要覆盖的完整粒子选项,结构等同于ISourceOptions

其中default子对象(ThemeDefault类,见 plugins/themes/src/Options/Classes/ThemeDefault.ts)的属性如下:

属性类型默认值说明
autobooleanfalsetrue时,当mode与操作系统主题匹配,主题会被自动应用
modeThemeMode \| keyof typeof ThemeModeThemeMode.any默认主题对应的模式
valuebooleanfalse标记/取消标记该主题在指定模式下的「默认」地位

默认 JSON 示例

官方文档给出的默认结构如下,可作为最小配置骨架:

{ "name": "", "default": { "auto": false, "mode": "any", "value": false } }

ThemeMode 枚举

mode可取值为ThemeMode枚举导出的三个常量,定义于 plugins/themes/src/ThemeMode.ts:

export enum ThemeMode { any = "any", dark = "dark", light = "light", }

即支持字符串形式"any""dark""light"或枚举形式ThemeMode.anyThemeMode.darkThemeMode.lightdark/light用于匹配操作系统深色/浅色外观,any表示不限定模式。

三、配置加载的源码级原理

1.Theme.load:合并而非替换

当配置被加载时,每个主题对象调用Theme.load(data)(plugins/themes/src/Options/Classes/Theme.ts):

  • name通过loadProperty赋值;
  • default交由ThemeDefault.load分别加载automodevalue三个属性;
  • options若存在,则通过deepExtend({}, data.options)深拷贝合并ISourceOptions

也就是说,主题的options是一份完整的、可独立覆盖的选项对象,加载后会整体覆盖当前实例的选项,而不是增量补丁。

2.ThemesPlugin.loadOptions:注册与默认主题查找

插件的loadOptions方法(plugins/themes/src/ThemesPlugin.ts)负责把配置中的themes数组注册进options.themes,并挂载两个内部函数:

  • findDefaultTheme(mode):优先查找default.value === truedefault.mode === mode的主题;若没有精确匹配,则回退查找default.value === truedefault.mode === ThemeMode.any的主题;
  • setTheme(name?)
    • 传入name时,按名称找到对应主题并调用options.load(chosenTheme.options)加载其选项;
    • 不传name时,通过safeMatchMedia("(prefers-color-scheme: dark)")检测客户端是否为深色模式,再根据结果选择 dark/light 的默认主题并加载。

同时,插件会把查找到的默认主题名称写入options.defaultThemes.darkoptions.defaultThemes.light(该字段在 engine/src/Options/Classes/Options.ts 声明),供运行时监听系统主题变化使用。

needsPlugin判断逻辑为!!options?.themes?.length,即只要配置中出现themes数组即启用插件。

四、运行时行为:自动主题与手动切换

1. 监听系统深色/浅色模式

插件实例ThemesPluginInstance(plugins/themes/src/ThemesPluginInstance.ts)在init()时创建matchMedia("(prefers-color-scheme: dark)")监听器,并在start()时注册change事件。

当操作系统切换深色/浅色外观时,#handleThemeChange会读取options.defaultThemes.dark/defaultThemes.light,找到对应名称的主题,仅当该主题的default.auto === true时才自动调用container.loadTheme(themeName)

if (theme?.default.auto) { void container.loadTheme?.(themeName); }

这正是auto属性的作用:它决定了「跟随系统外观」是否自动生效。stop()时会移除监听器,避免内存泄漏。

2.loadTheme与容器刷新

container.loadTheme(name?)(同文件 plugins/themes/src/ThemesPluginInstance.ts)在设置container.currentTheme = name之后调用container.refresh(),让粒子实例按新主题的选项重新初始化。容器相关能力(currentThemeloadThememanageMediaMatchthemeMatchMedia等)都定义在 plugins/themes/src/types.ts 的ThemesContainer类型中。

因此,运行时切换主题的链路为:用户调用loadTheme(name)→ 记录currentThemecontainer.refresh()→ 按新选项重绘粒子

五、实战:定义深色/浅色主题并切换

1. 加载插件

使用前必须先注册插件(支持懒加载入口 plugins/themes/src/index.lazy.ts):

import { tsParticles } from "@tsparticles/engine"; import { loadThemesPlugin } from "@tsparticles/plugin-themes"; await loadThemesPlugin(tsParticles);

2. 定义多套主题

以下配置定义了两套主题:"dark""light",其中深色主题在dark模式下为默认(default.value: true),并开启auto以跟随系统外观自动切换:

{ "themes": [ { "name": "dark", "default": { "auto": true, "mode": "dark", "value": true }, "options": { "background": { "color": "#0b0f19" }, "particles": { "color": { "value": "#4dc9f6" }, "links": { "color": "#3f8efc" } } } }, { "name": "light", "default": { "auto": true, "mode": "light", "value": true }, "options": { "background": { "color": "#f5f7fb" }, "particles": { "color": { "value": "#1f2937" }, "links": { "color": "#6b7280" } } } } ] }

要点:

  • name必须唯一,插件加载时若遇到同名主题会复用已有对象并重新load(见 plugins/themes/src/ThemesPlugin.ts);
  • options中只需填写该主题需要覆盖的字段,未声明的字段沿用全局选项;
  • 想让「无名称」的调用(如setTheme()不传参)生效,需要至少一个default.value: true的主题;若同时存在 dark/light 两个模式的默认主题,系统会根据客户端外观二选一。

3. 运行时手动切换主题

在初始化完成后,可通过容器 API 按名称切换(也可通过setTheme内部函数):

// 按名称切换到 "light" 主题 await tsParticles.domItem(0)?.loadTheme?.("light");

不传参数时,插件会根据当前系统外观自动挑选 dark 或 light 的默认主题(等价于调用setTheme()的无参分支,见 plugins/themes/src/ThemesPlugin.ts)。

六、使用建议与注意事项

  1. auto只影响自动切换:系统外观变化时,只有default.auto === true的主题会被自动应用;手动调用loadTheme(name)不受此限制。
  2. 默认主题的语义default.value: true决定该主题在对应mode(或any兜底)下成为默认主题;options.defaultThemes.dark/light会在加载配置时自动计算。
  3. mode的值域:只能是ThemeMode枚举中的anydarklight三者之一,写入其他字符串无法与系统外观匹配。
  4. 主题即覆盖options采用deepExtend深合并,适合存放该主题独有的背景色、粒子颜色、数量、动画等差异化配置。
  5. 性能提示:切换主题会触发container.refresh()重建粒子,属于重量级操作;如需频繁切换,建议控制主题数量并避免在切换时做其他昂贵操作。

结语

themes插件以极简的三个配置项(namedefaultoptions)+ 一个三值枚举ThemeMode完成了「多套粒子配置 + 深色模式适配 + 运行时切换」的完整能力。结合本文给出的源码调用链(loadOptionsfindDefaultTheme/setThemeloadThemerefresh)与实战配置,你可以直接在自己的 tsParticles 项目中实现跟随系统的深色/浅色粒子背景,或按业务需要(如用户手动选择)动态切换整套视觉效果。

【免费下载链接】tsparticlestsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.项目地址: https://gitcode.com/GitHub_Trending/ts/tsparticles

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询