关于 pixijs-color
面向 PixiJS 开发者的 Color 类使用技能,讲解颜色格式转换、组件读写和颜色值处理。还介绍共享实例与复用输出缓冲区,以适用于高频渲染路径。
主要功能
- 01解析多种颜色输入格式
- 02转换为十六进制、数值或数组
- 03读取与设置颜色分量
- 04生成预乘颜色值
- 05复用输出缓冲区
适用场景
- 01将颜色转换为 GPU 所需格式
- 02处理精灵 tint 或图形填充颜色
- 03在渲染循环中减少对象分配
- 04检查外部输入是否为颜色格式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pixijs/ pixijs-skills --skill pixijs-color安装后在 Claude Code 中输入/pixijs-color确认已加载。
详细介绍
Color 类用于创建和转换颜色,可用于色调、填充、描边,以及 PixiJS 接受 ColorSource 的任何地方。大多数 API 都直接接受原始十六进制值或字符串,因此只有在转换格式或操作颜色值时,才需要显式使用 new Color(...)。
快速入门
const fillColor = new Color("#ff6600");
console.log(fillColor.toHex()); // '#ff6600'
console.log(fillColor.toNumber()); // 0xff6600
console.log(fillColor.toArray()); // [1, 0.4, 0, 1]
const g = new Graphics().rect(0, 0, 200, 100).fill(fillColor);
app.stage.addChild(g);
const sprite = Sprite.from("hero.png");
sprite.tint = "dodgerblue";
app.stage.addChild(sprite);
const t = Color.shared.setValue(0xffffff).multiply([1, 0.5, 0.5]).toNumber();
sprite.tint = t;
相关技能: pixijs-scene-graphics(填充/描边颜色)、pixijs-scene-sprite(色调)、pixijs-blend-modes(合成)。
核心模式
接受的输入格式
import { Color } from "pixi.js";
// Hex integer
new Color(0xff0000);
// Hex strings
new Color("#ff0000");
new Color("#f00");
new Color("ff0000");
// CSS color names
new Color("red");
new Color("dodgerblue");
// RGB/RGBA objects (components 0-255)
new Color({ r: 255, g: 0, b: 0 });
new Color({ r: 255, g: 0, b: 0, a: 0.5 });
// HSL/HSLA objects
new Color({ h: 0, s: 100, l: 50 });
new Color({ h: 0, s: 100, l: 50, a: 0.5 });
// HSV/HSVA objects
new Color({ h: 0, s: 100, v: 100 });
// CSS strings
new Color("rgb(255, 0, 0)");
new Color("rgba(255, 0, 0, 0.5)");
new Color("hsl(0, 100%, 50%)");
// Normalized 0-1 arrays (Float32Array or plain arrays)
new Color([1, 0, 0]); // RGB
new Color([1, 0, 0, 0.5]); // RGBA
// Uint8 arrays (components 0-255)
new Color(new Uint8Array([255, 0, 0]));
new Color(new Uint8ClampedArray([255, 0, 0, 128]));
// 8-digit hex with alpha
new Color("#ff0000ff");
new Color("#f00f");
// Copy from another Color instance
const red = new Color("red");
const copy = new Color(red);
转换方法
import { Color } from "pixi.js";
const color = new Color("#ff6600");
color.toHex(); // '#ff6600'
color.toHexa(); // '#ff6600ff' (hex with alpha)
color.toNumber(); // 0xff6600
color.toArray(); // [1, 0.4, 0, 1] (normalized RGBA)
color.toRgbArray(); // [1, 0.4, 0] (normalized RGB, no alpha)
color.toRgbaString(); // 'rgba(255,102,0,1)'
color.toRgba(); // { r: 1, g: 0.4, b: 0, a: 1 }
color.toRgb(); // { r: 1, g: 0.4, b: 0 }
color.toUint8RgbArray(); // [255, 102, 0]
// setValue() is the chainable way to change a color's value
color.setValue(0xff0000).toHex(); // '#ff0000'
分量访问
import { Color } from "pixi.js";
const color = new Color("rgba(255, 128, 0, 0.8)");
color.red; // 1
color.green; // ~0.502
color.blue; // 0
color.alpha; // 0.8
所有分量 getter 返回的都是归一化到 0-1 的值。
操作
import { Color } from "pixi.js";
const color = new Color("red");
// Set alpha (chainable)
color.setAlpha(0.5);
// Multiply with another color (destructive, modifies in place)
color.multiply(0x808080);
// Premultiply alpha (destructive, RGB channels multiplied by alpha)
color.premultiply(0.8);
// Premultiply alpha only (RGB unchanged)
color.premultiply(0.8, false);
// Chain operations
new Color("white").setAlpha(0.5).multiply([0.8, 0.2, 0.2]);
multiply() 和 premultiply() 会直接修改颜色,并将 value 设为 null(原始格式会丢失)。
以非破坏方式输出预乘颜色
import { Color } from "pixi.js";
const color = new Color("red").setAlpha(0.5);
const packed = color.toPremultiplied(color.alpha); // 0x7F7F0000
const alphaOnly = color.toPremultiplied(color.alpha, false); // 0x7FFF0000
toPremultiplied(alpha, applyToRGB?) 返回一个 32 位 0xAARRGGBB 整数,不会修改 this。在批处理器和色调计算中,如果需要重复使用源颜色,请使用此方法。当 applyToRGB 为 false 时,只会打包 alpha 字节;RGB 保持完整值。
重用输出缓冲区
import { Color } from "pixi.js";
const rgba = new Float32Array(4);
const rgb = new Float32Array(3);
const rgb8 = new Uint8Array(3);
app.ticker.add(() => {
Color.shared.setValue(sprite.tint).toArray(rgba).toRgbArray(rgb);
Color.shared.toUint8RgbArray(rgb8);
});
toArray(out?)、toRgbArray(out?) 和 toUint8RgbArray(out?) 接受可重用的 number[]、Float32Array、Uint8Array 或 Uint8ClampedArray,并将结果写入其中。在高频路径中传入自己的缓冲区,以避免每帧分配内存;省略参数时,Color 实例会返回其内部缓存数组。
为 GPU 缓冲区打包
| 方法 | 返回值 |
|---|---|
toBgrNumber() | 24 位 0xBBGGRR 整数,R/B 已交换 |
toLittleEndianNumber() | 相同的 24 位交换格式,便于写入小端顶点数据 |
这两种方法开销很低,适合直接将颜色写入打包的顶点属性。
用 Color.shared 执行临时操作
import { Color } from "pixi.js";
// One-off conversion without allocating a new Color
const hex = Color.shared.setValue("#ff6600").toNumber();
const arr = Color.shared.setValue(0xff0000).toArray();
Color.shared 是一个单例,可避免每次调用都分配新的 Color。这在渲染循环或每帧色调计算等高频路径中尤为重要,因为反复创建 new Color() 会增加 GC 压力。不要保存对它的引用;其他代码可能会修改它。
import { Color } from "pixi.js";
// Good: reuse shared instance in a per-frame callback
app.ticker.add(() => {
const t = performance.now() / 1000;
sprite.tint = Color.shared
.setValue("white")
.multiply([Math.sin(t) * 0.5 + 0.5, 0.2, 0.8])
.toNumber();
});
验证输入
import { Color } from "pixi.js";
Color.isColorLike("red"); // true
Color.isColorLike("#ff0000"); // true
Color.isColorLike(0xff0000); // true
Color.isColorLike([1, 0, 0]); // true
Color.isColorLike({ r: 1, g: 0, b: 0 }); // true
Color.isColorLike({ foo: 1 }); // false
Color.isColorLike(null); // false
Color.isColorLike() 会检查结构形式(字符串、数字、数组或可识别的对象)。它不会验证字符串是否为有效的 CSS 颜色名称,也不会检查数组值是否在范围内。在将用户输入传递给 new Color() 或 setValue() 之前,可将它用作类型守卫。
常见错误
[MEDIUM] 误以为 toRgba() 会返回 0-255 范围的值
错误:
import { Color } from "pixi.js";
const { r, g, b } = new Color({ r: 255, g: 128, b: 0 }).toRgba();
// r = 1, g = ~0.502, b = 0 (NOT 255, 128, 0)
正确:
import { Color } from "pixi.js";
// Use toUint8RgbArray() for 0-255 output
const [r, g, b] = new Color({ r: 255, g: 128, b: 0 }).toUint8RgbArray();
// r = 255, g = 128, b = 0
RGB 对象的_输入_使用 0-255 范围({ r: 255, g: 0, b: 0 }),但所有输出方法(toRgba()、toRgb()、toArray()、toRgbArray())都会将值归一化到 0-1。需要为 CSS 或外部 API 获取 0-255 整数时,请使用 toUint8RgbArray()。
[MEDIUM] 在颜色数组中使用 0-255 范围
错误:
import { Color } from "pixi.js";
new Color([255, 0, 0]); // NOT red; values are interpreted as 0-1
正确:
import { Color } from "pixi.js";
new Color([1, 0, 0]); // red via normalized array
new Color(0xff0000); // red via hex
new Color("red"); // red via CSS name
new Color(new Uint8Array([255, 0, 0])); // red via Uint8Array (0-255)
普通数字数组(number[] 和 Float32Array)使用归一化的 0-1 范围。[255, 0, 0] 会被限制为 [1, 0, 0],因为数值会被限制在范围内;但 [200, 100, 50] 不会得到预期的颜色。对于 0-255 范围的输入,请使用 Uint8Array 或 Uint8ClampedArray。
[MEDIUM] 使用 utils.string2hex 或 utils.hex2string
错误:
import { utils } from "pixi.js";
const hex = utils.string2hex("#ff0000");
正确:
import { Color } from "pixi.js";
const hex = new Color("#ff0000").toNumber();
const str = new Color(0xff0000).toHex();
utils 命名空间已在 v8 中移除。所有颜色转换都请使用 Color 类。