tsParticles 粒子填充详解:paint.fill 的颜色、不透明度与渲染链路
tsParticles 粒子填充详解paint.fill 的颜色、不透明度与渲染链路【免费下载链接】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本文以 markdown/Options/Particles/Fill.md 中的粒子填充Fill选项文档为主体结合 engine 引擎源码逐层展开你将理解paint.fill的enable、color、opacity三个属性的类型与默认值掌握静态值、随机区间与颜色动画等多种配置写法并能从PaintUpdater到RenderManager的完整渲染调用链中看清这些配置最终如何作用到 Canvas 上。一、Fill 是什么粒子内部的“底色”在 tsParticles 中粒子的绘制被统一归组到paint选项下paint.fill负责粒子内部填充色paint.stroke负责描边二者还可共享一个回退色paint.color分组与回退规则详见 markdown/Options/Particles/Paint.md。paint.fill的核心语义是用指定的内部颜色把粒子形状填实。当fill.enable为true时粒子内部被填充色填满当设为false时粒子只保留描边outline呈现空心效果。对应接口定义在 engine/src/Options/Interfaces/Particles/IFill.ts接口注释明确写道Particle fill, fills the particle with the given color粒子填充用给定颜色填充粒子该文档同时是 TypeScript 声明文件中的 JSDoc 来源——IFill 接口 与 Fill 类 上的[[include:Options/Particles/Fill.md]]标记会把这份 Markdown 直接内嵌进类型文档因此本文与 IDE 中悬浮查看IFill类型时看到的说明是同一来源。二、属性详解enable / color / opacity文档中定义的三个属性与源码实现一一对应。对照 Fill 类实现export class Fill extends OptionLoaderIFill implements IFill { color?: AnimatableColor; enable true; opacity: RangeValue 1; protected doLoad(data: RecursivePartialIFill): void { if (data.color ! undefined) { this.color AnimatableColor.create(this.color, data.color); } loadProperty(this, enable, data.enable); loadRangeProperty(this, opacity, data.opacity); } }2.1 enableboolean—— 默认truetrue粒子内部被填充色填满false跳过填充仅保留paint.stroke描边得到空心粒子。从源码结构看enable的解析走loadProperty属于普通标量加载而真正的“是否调用context.fill()”发生在渲染阶段见第四节。2.2 colorIAnimatableColor | IRangeColor填充色支持两类颜色模型IAnimatableColor可携带animation子配置对 H/S/L 任一通道做动画例如让填充色在多种色调间循环IRangeColor以value传入颜色数组时引擎会从区间中随机取色实现“每个粒子颜色略有不同”的效果。源码中doLoad对color的处理是AnimatableColor.create(this.color, data.color)即把传入的部分数据合并进AnimatableColor实例——这意味着color.value既可写单个颜色字符串也可写字符串数组随机范围与 markdown/Options/Particles/Paint.md 中的[#60a5fa, #a78bfa, #f472b6]示例一致。颜色模型的完整规则HSL 解析、随机取值、动画通道可继续参考 markdown/Color.md。2.3 opacitynumber | RangeValue—— 默认1填充不透明度取值范围0..1。类型RangeValue在 engine/src/Types/RangeValue.ts 中定义为number | IRangeValue即既接受静态数字也接受{ min, max }形式的区间对象{ particles: { paint: { fill: { opacity: { min: 0.4, max: 0.9 } } } } }loadRangeProperty会保留区间对象而非立即取值——具体的随机化发生在粒子初始化阶段下文PaintUpdater中的getRangeValue调用因此每个粒子各自独立抽取一次不透明度。三、默认行为与历史兼容文档给出的三条默认行为均可在引擎源码中找到落点enable默认为trueFill类字段声明即enable trueFill.ts。opacity默认为1字段声明opacity: RangeValue 1Fill.ts。未写paint.fill时粒子保持“白色实心”的历史行为ParticlesOptions 构造函数 显式初始化了回退值this.paint new Paint(); this.paint.color new AnimatableColor(); this.paint.color.value #fff; this.paint.fill new Fill(); this.paint.fill.enable true;也就是说即使你在配置里完全没有paint段引擎也会得到一个白色、已启用填充的默认粒子只有当你显式配置paint.stroke或使用调色板palette时这一默认才会被覆盖。另一个值得注意的机制Paint 类 通过loadLazyProperty(this, fill, data.fill, () new Fill())惰性创建Fill实例——只有当配置里出现fill键时才new Fill()并加载数据避免为无关配置构造无用的对象。四、从配置到像素fill 的渲染调用链配置项写入后引擎按“加载 → 初始化粒子 → 每帧渲染”三步消费它们。以下调用链均可在仓库中验证4.1 初始化PaintUpdater把 Fill 展开到每个粒子updaters/paint/src/PaintUpdater.ts 是paint选项的粒子初始化器其中init方法完成三个关键赋值particle.fillEnabled fill.enable; particle.fillOpacity getRangeValue(fill.opacity); particle.fillAnimation fillColor.animation; const fillHslColor rangeColorToHsl(this.#pluginManager, fillColor); if (fillHslColor) { particle.fillColor getHslAnimationFromHsl( fillHslColor, particle.fillAnimation, container.retina.reduceFactor, ); }这段代码解释了第二节三个属性的确切归宿fill.enable→particle.fillEnabled决定后续是否执行context.fill()fill.opacity→particle.fillOpacitygetRangeValue在此处把区间对象随机化为具体数字静态值则原样通过fill.color→ 经AnimatableColor与rangeColorToHsl解析为 HSL 值再结合animation包装成可动画的particle.fillColor。若配置中没有fill段PaintUpdater会显式关闭填充particle.fillEnabled false、fillColor undefined与 markdown/Options/Particles/Paint.md 中“paint.color是 fill/stroke 的回退色”的语义相衔接paint.color会作为基础色传入AnimatableColor.create当fill.color未设置时兜底生效。PaintUpdater.update则负责颜色动画的逐帧推进只要 H/S/L 任一通道启用了动画isEnabled判定就对particle.fillColor执行updateColor。4.2 每帧渲染RenderManager写入 Canvas 样式渲染入口在 engine/src/Core/RenderManager.tsconst pfColor particle.getFillColor(), psColor particle.getStrokeColor(); // ... const { fillOpacity, opacity, strokeOpacity } particle.getOpacity(), fill fColor ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity) : undefined, stroke sColor ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity) : fill;两个要点最终fillStyle的透明度是fillOpacity × opacity粒子整体不透明度的乘积——所以paint.fill.opacity与全局opacity效果是叠加而非覆盖的若插件未提供颜色fColor ?? pfColor引擎回落到粒子自身的getFillColor()。getFillColor()的实现见 Particle.ts它从particle.fillColor的动画状态取出当前 HSL 并应用颜色修饰器保证动画帧取到的是最新颜色。真正把颜色画上去的地方是#drawShapeRenderManager.tsif (fill) { context.fill(); } if (stroke) { context.stroke(); }这里的fill布尔值来自#drawParticle中的fill: fillEnabledfillEnabled !!particle.fillEnabled见 RenderManager.ts。至此文档中“false时仅描边”的描述在代码层面得到印证fillEnabled为false时形状路径依然绘制但跳过context.fill()只走context.stroke()。五、配置示例5.1 文档原始示例静态红色填充{ particles: { paint: { fill: { enable: true, color: { value: #ff0000 }, opacity: 0.9 } } } }每个粒子为 90% 不透明度的红色实心。5.2 区间色 区间不透明度随机化填充color.value传数组触发随机取色opacity传{min, max}区间见 2.3 节{ particles: { paint: { fill: { enable: true, color: { value: [#60a5fa, #a78bfa, #f472b6] }, opacity: { min: 0.5, max: 1 } } } } }5.3 空心粒子关闭 fill、保留 stroke利用fill.enable: false与paint.stroke组合得到只有描边的空心形状paint.color作为描边回退色{ particles: { paint: { color: { value: #14b8a6 }, fill: { enable: false }, stroke: { width: 2, color: { value: #ffffff } } } } }5.4 paint 数组多个填充变体ParticlesOptions.doLoad 支持paint传数组SingleOrMultiplePaint数组中每个元素是一个完整的Paint变体各自可含fill/stroke引擎用itemFromSingleOrMultiple(options.paint, particle.id, options.reduceDuplicates)按粒子id选取变体reduceDuplicates: true时去重复用。这让“50% 实心 50% 空心”或多种配色并存成为可能。5.5 与调色板palette的交互文档 Notes 提到“paint同时包含fill和stroke使用particles.palette时调色板可提供默认fill值”。实现位于 ParticlesOptions.#importPalette引擎从调色板插件取出颜色变体把variant.fill映射为标准{ color: { value }, enable, opacity }的fill结构variant.stroke同理再作为paint整体load进选项同时启用blend混合模式。调色板数据结构示例可参考 palettes/ 目录。六、要点小结属性类型默认值作用paint.fill.enablebooleantrue是否填充粒子内部false时仅描边paint.fill.colorIAnimatableColor|IRangeColor回退到paint.color默认#fff填充色支持区间随机与 HSL 通道动画paint.fill.opacitynumber |{min,max}1填充不透明度0..1与粒子整体opacity相乘配置解析Fill 类 惰性加载loadProperty/loadRangeProperty/AnimatableColor.create粒子初始化PaintUpdater 将 Fill 展开为fillEnabled/fillOpacity/fillColor三个粒子字段并在无fill配置时显式关闭填充渲染消费RenderManager 依据fillEnabled决定是否调用context.fill()填充透明度为fillOpacity × opacity。延伸阅读paint分组总览见 markdown/Options/Particles/Paint.md描边选项见 markdown/Options/Particles/Stroke.md颜色模型见 markdown/Color.md。【免费下载链接】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),仅供参考