All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 47s
102 lines
4.2 KiB
TypeScript
102 lines
4.2 KiB
TypeScript
import { _decorator, UIRenderer, Component, Color, clamp, director, Director, Sprite, Label } from 'cc';
|
||
import { DEV, JSB } from 'cc/env';
|
||
const { ccclass, property, executeInEditMode, requireComponent, menu } = _decorator;
|
||
@ccclass
|
||
@executeInEditMode
|
||
@requireComponent(UIRenderer)
|
||
@menu('Public/Palette')
|
||
export class Palette extends Component {
|
||
@property
|
||
private _colorLB: Color = new Color(255, 255, 255, 255);
|
||
@property({ displayName: DEV && '↙ 左下' })
|
||
public get colorLB() { return this._colorLB };
|
||
public set colorLB(value: Color) {
|
||
this._colorLB = value;
|
||
this.updateColor();
|
||
}
|
||
@property
|
||
private _colorRB: Color = new Color(255, 255, 255, 255);
|
||
@property({ displayName: DEV && '↘ 右下' })
|
||
public get colorRB() { return this._colorRB };
|
||
public set colorRB(value: Color) {
|
||
this._colorRB = value;
|
||
this.updateColor();
|
||
}
|
||
@property
|
||
private _colorLT: Color = new Color(255, 255, 255, 255);
|
||
@property({ displayName: DEV && '↖ 左上' })
|
||
private get colorLT() { return this._colorLT };
|
||
private set colorLT(value: Color) {
|
||
this._colorLT = value;
|
||
this.updateColor();
|
||
}
|
||
@property
|
||
private _colorRT: Color = new Color(255, 255, 255, 255);
|
||
@property({ displayName: DEV && '↗ 右上' })
|
||
private get colorRT() { return this._colorRT };
|
||
private set colorRT(value: Color) {
|
||
this._colorRT = value;
|
||
this.updateColor();
|
||
}
|
||
@property
|
||
private _hueRatio: number = 1;
|
||
@property({ range: [0, 1], step: 0.01, slide: true, displayName: '🌈 色相' })
|
||
get hueRatio() { return this._hueRatio; }
|
||
set hueRatio(val) {
|
||
this._hueRatio = clamp(val, 0, 1);
|
||
this.updateHueRatio();
|
||
this.updateColor();
|
||
}
|
||
@property
|
||
private _darkness: number = 1;
|
||
@property({ range: [0, 1], step: 0.01, slide: true, displayName: '🌞 暗度' })
|
||
get darkness() { return this._darkness; }
|
||
set darkness(val) {
|
||
this._darkness = clamp(val, 0, 1);
|
||
this.updateColor();
|
||
}
|
||
private ur: UIRenderer = null;
|
||
private hue: number[] = [1, 1, 1]; //色相分量
|
||
protected onLoad() {
|
||
this.ur = this.node.getComponent(UIRenderer);
|
||
if (!(this.ur instanceof Sprite || this.ur instanceof Label)) {
|
||
console.warn('Palette只对Sprite和Label有效!');
|
||
this.destroy();
|
||
return;
|
||
}
|
||
this.ur['_useVertexOpacity'] = true; //启用顶点透明度(否则透明度只受color.a影响)
|
||
}
|
||
protected onEnable() {
|
||
this.updateHueRatio();
|
||
director.once(Director.EVENT_AFTER_DRAW, this.updateColor, this);
|
||
}
|
||
protected onDisable() {
|
||
if (!this.ur['_renderData']) return;
|
||
let vb = this.ur['_renderData'].chunk.vb;
|
||
let color = this.ur.color;
|
||
vb[5] = vb[14] = vb[23] = vb[32] = color.r / 255;
|
||
vb[6] = vb[15] = vb[24] = vb[33] = color.g / 255;
|
||
vb[7] = vb[16] = vb[25] = vb[34] = color.b / 255;
|
||
vb[8] = vb[17] = vb[26] = vb[35] = color.a / 255;
|
||
}
|
||
private updateColor() {
|
||
let vb = this.ur['_renderData'].chunk.vb;
|
||
let lb = this._colorLB, rb = this._colorRB, lt = this._colorLT, rt = this._colorRT;
|
||
let d = this._darkness / 255, h = this.hue, r = h[0] * d, g = h[1] * d, b = h[2] * d;
|
||
vb[5] = lb.r * r; vb[6] = lb.g * g; vb[7] = lb.b * b; vb[8] = lb.a / 255;
|
||
vb[14] = rb.r * r; vb[15] = rb.g * g; vb[16] = rb.b * b; vb[17] = rb.a / 255;
|
||
vb[23] = lt.r * r; vb[24] = lt.g * g; vb[25] = lt.b * b; vb[26] = lt.a / 255;
|
||
vb[32] = rt.r * r; vb[33] = rt.g * g; vb[34] = rt.b * b; vb[35] = rt.a / 255;
|
||
}
|
||
private updateHueRatio(): void {
|
||
const step = 1 / 7;
|
||
let hueRatio = this._hueRatio;
|
||
if (hueRatio < step) this.hue = [1, hueRatio / step, 0];
|
||
else if (hueRatio < step * 2) this.hue = [2 - hueRatio / step, 1, 0];
|
||
else if (hueRatio < step * 3) this.hue = [0, 1, hueRatio / step - 2];
|
||
else if (hueRatio < step * 4) this.hue = [0, 4 - hueRatio / step, 1];
|
||
else if (hueRatio < 5 * step) this.hue = [hueRatio / step - 4, 0, 1];
|
||
else if (hueRatio < 6 * step) this.hue = [1, 0, 6 - hueRatio / step];
|
||
else { this.hue = [1, hueRatio / step - 6, hueRatio / step - 6]; }
|
||
}
|
||
} |