我正在编写一个颜色类,它用一个整数存储颜色,并且有r
,g
和b
个getter和setter,它们从那个整数中操作/检索
export default class Colour {
private col: number;
public get r () {
return (this.col >> 16) & 0xFF;
}
public get g () {
return (this.col >> 8) & 0xFF;
}
public get b () {
return (this.col >> 0) & 0xFF;
}
// setters here
constructor(colour: string);
constructor(redGreenBlue: number);
constructor(red: number, green: number, blue: number);
constructor(colourOrRed: string | number, green?: number, blue?: number) {
if (typeof colourOrRed == "string") {
if (colourOrRed.startsWith("#")) colourOrRed = colourOrRed.slice(1);
this.col = parseInt(colourOrRed, 16);
} else {
colourOrRed = Maths.clamp(colourOrRed, 0, 255);
green = typeof green == "number" ? Maths.clamp(green, 0, 255) : colourOrRed;
blue = typeof blue == "number" ? Maths.clamp(blue, 0, 255) : colourOrRed;
this.col = (1 << 24) + (colourOrRed << 16) + (green << 8) + blue;
}
}
}
我能够想到的唯一方法就是从颜色中获取其他通道,然后像在构造函数中那样设置颜色整数。
public set r (red: number) {
red = Maths.clamp(red, 0, 255);
this.col = (1 << 24) + (red << 16) + (this.g << 8) + this.b;
}
如何分别设置红色,绿色和蓝色通道,而无需检索过去的值?有没有办法做到这一点?我假设有一些我可以使用的花哨的按位操作,但我不知道如何(这段代码中的按位运算符我从其他答案中复制了)。
答案 0 :(得分:2)
您可以使用位掩码保持其他颜色通道不变,只添加特定通道的钳位值;与提取频道的颜色几乎相同,只是向后。
由于我不知道如何实现Maths.clamp()
,以及它增加了多少开销,我更喜欢这里的显式版本。
export default class Colour {
private col: number;
public get r () {
return (this.col >> 16) & 0xFF;
}
public set r (value: number) {
this.col = (this.col & 0x0100FFFF) | (value>0? value<255? value<<16: 0xFF0000: 0);
}
public get g () {
return (this.col >> 8) & 0xFF;
}
public set g (value: number) {
this.col = (this.col & 0x01FF00FF) | (value>0? value<255? value<<8: 0x00FF00: 0);
}
public get b () {
return (this.col >> 0) & 0xFF;
}
public set b (value: number) {
this.col = (this.col & 0x01FFFF00) | (value>0? value<255? value: 0x0000FF: 0);
}
}
编辑:更新了掩码以包含/保留构造函数中的1<<24
位。在将颜色转换为HEX表示时,避免添加前导零的必要性可能是一种黑客攻击。类似于this.col.toString(16).substr(-6)
。