diff --git a/cocos/core/math/color.ts b/cocos/core/math/color.ts
index 16fe420c8ee..2fc6f6cee28 100644
--- a/cocos/core/math/color.ts
+++ b/cocos/core/math/color.ts
@@ -39,6 +39,9 @@ const G_INDEX = 1;
const B_INDEX = 2;
const A_INDEX = 3;
+const mathAbs = Math.abs;
+const mathMax = Math.max;
+
/**
* @en Representation of RGBA colors.
* Each color component is an integer value with a range from 0 to 255.
@@ -104,11 +107,12 @@ export class Color extends ValueType implements Modifiable {
* ```
*/
public static toVec4 (color: Color, out?: Vec4): Vec4 {
+ const sourceData = color._data;
out = out !== undefined ? out : new Vec4();
- out.x = color._data[R_INDEX] * toFloat;
- out.y = color._data[G_INDEX] * toFloat;
- out.z = color._data[B_INDEX] * toFloat;
- out.w = color._data[A_INDEX] * toFloat;
+ out.x = sourceData[R_INDEX] * toFloat;
+ out.y = sourceData[G_INDEX] * toFloat;
+ out.z = sourceData[B_INDEX] * toFloat;
+ out.w = sourceData[A_INDEX] * toFloat;
return out;
}
/**
@@ -122,10 +126,11 @@ export class Color extends ValueType implements Modifiable {
*/
public static fromVec4 (value: Vec4, out?: Color): Color {
out = out === undefined ? new Color() : out;
- out._data[R_INDEX] = value.x / toFloat;
- out._data[G_INDEX] = value.y / toFloat;
- out._data[B_INDEX] = value.z / toFloat;
- out._data[A_INDEX] = value.w / toFloat;
+ const outData = out._data;
+ outData[R_INDEX] = value.x / toFloat;
+ outData[G_INDEX] = value.y / toFloat;
+ outData[B_INDEX] = value.z / toFloat;
+ outData[A_INDEX] = value.w / toFloat;
return out;
}
/**
@@ -313,11 +318,11 @@ export class Color extends ValueType implements Modifiable {
* @zh 排除浮点数误差的颜色近似等价判断
*/
public static equals (a: Out, b: Out, epsilon = EPSILON): boolean {
- const hasInf = Math.abs(a.r) === Infinity || Math.abs(a.g) === Infinity || Math.abs(a.b) === Infinity || Math.abs(a.a) === Infinity;
- return !hasInf && (Math.abs(a.r - b.r) <= epsilon * Math.max(1.0, Math.abs(a.r), Math.abs(b.r))
- && Math.abs(a.g - b.g) <= epsilon * Math.max(1.0, Math.abs(a.g), Math.abs(b.g))
- && Math.abs(a.b - b.b) <= epsilon * Math.max(1.0, Math.abs(a.b), Math.abs(b.b))
- && Math.abs(a.a - b.a) <= epsilon * Math.max(1.0, Math.abs(a.a), Math.abs(b.a)));
+ const hasInf = mathAbs(a.r) === Infinity || mathAbs(a.g) === Infinity || mathAbs(a.b) === Infinity || mathAbs(a.a) === Infinity;
+ return !hasInf && (mathAbs(a.r - b.r) <= epsilon * mathMax(1.0, mathAbs(a.r), mathAbs(b.r))
+ && mathAbs(a.g - b.g) <= epsilon * mathMax(1.0, mathAbs(a.g), mathAbs(b.g))
+ && mathAbs(a.b - b.b) <= epsilon * mathMax(1.0, mathAbs(a.b), mathAbs(b.b))
+ && mathAbs(a.a - b.a) <= epsilon * mathMax(1.0, mathAbs(a.a), mathAbs(b.a)));
}
/**
@@ -442,11 +447,12 @@ export class Color extends ValueType implements Modifiable {
*/
public equals (other: Readonly): boolean {
const otherColor = other as Color;
+ const thisData = this._data;
// otherColor may not be Color instance if invoked by tween action, so use getter to get property values.
- return other && this._data[R_INDEX] === otherColor.r
- && this._data[G_INDEX] === otherColor.g
- && this._data[B_INDEX] === otherColor.b
- && this._data[A_INDEX] === otherColor.a;
+ return other && thisData[R_INDEX] === otherColor.r
+ && thisData[G_INDEX] === otherColor.g
+ && thisData[B_INDEX] === otherColor.b
+ && thisData[A_INDEX] === otherColor.a;
}
/**
@@ -549,12 +555,13 @@ export class Color extends ValueType implements Modifiable {
* ```
*/
public toHEX (fmt: '#rgb' | '#rrggbb' | '#rrggbbaa' = '#rrggbb'): string {
+ const thisData = this._data;
const prefix = '0';
// #rrggbb
const hex = [
- (this._data[R_INDEX] < 16 ? prefix : '') + (this._data[R_INDEX]).toString(16),
- (this._data[G_INDEX] < 16 ? prefix : '') + (this._data[G_INDEX]).toString(16),
- (this._data[B_INDEX] < 16 ? prefix : '') + (this._data[B_INDEX]).toString(16),
+ (thisData[R_INDEX] < 16 ? prefix : '') + (thisData[R_INDEX]).toString(16),
+ (thisData[G_INDEX] < 16 ? prefix : '') + (thisData[G_INDEX]).toString(16),
+ (thisData[B_INDEX] < 16 ? prefix : '') + (thisData[B_INDEX]).toString(16),
];
const i = -1;
if (fmt === '#rgb') {
@@ -562,7 +569,7 @@ export class Color extends ValueType implements Modifiable {
hex[1] = hex[1][0];
hex[2] = hex[2][0];
} else if (fmt === '#rrggbbaa') {
- hex.push((this._data[A_INDEX] < 16 ? prefix : '') + (this._data[A_INDEX]).toString(16));
+ hex.push((thisData[A_INDEX] < 16 ? prefix : '') + (thisData[A_INDEX]).toString(16));
}
return hex.join('');
}
@@ -651,9 +658,10 @@ export class Color extends ValueType implements Modifiable {
break;
}
}
- this._data[R_INDEX] = r * 255;
- this._data[G_INDEX] = g * 255;
- this._data[B_INDEX] = b * 255;
+ const thisData = this._data;
+ thisData[R_INDEX] = r * 255;
+ thisData[G_INDEX] = g * 255;
+ thisData[B_INDEX] = b * 255;
return this;
}
@@ -707,23 +715,24 @@ export class Color extends ValueType implements Modifiable {
public set(other: Readonly): Color;
public set(r?: number, g?: number, b?: number, a?: number): Color;
public set (r?: number | Readonly, g?: number, b?: number, a?: number): Color {
+ const thisData = this._data;
if (typeof r === 'object') {
const other = r as Color;
if (other._data) {
// Tween action uses reflection to set color, so other may be just a IColorLike object.
// So should check _data property.
- this._data.set(other._data);
+ thisData.set(other._data);
} else {
- this._data[R_INDEX] = other.r ?? 0;
- this._data[G_INDEX] = other.g ?? 0;
- this._data[B_INDEX] = other.b ?? 0;
- this._data[A_INDEX] = other.a ?? 255;
+ thisData[R_INDEX] = other.r ?? 0;
+ thisData[G_INDEX] = other.g ?? 0;
+ thisData[B_INDEX] = other.b ?? 0;
+ thisData[A_INDEX] = other.a ?? 255;
}
} else {
- this._data[R_INDEX] = r ?? 0;
- this._data[G_INDEX] = g ?? 0;
- this._data[B_INDEX] = b ?? 0;
- this._data[A_INDEX] = a ?? 255;
+ thisData[R_INDEX] = r ?? 0;
+ thisData[G_INDEX] = g ?? 0;
+ thisData[B_INDEX] = b ?? 0;
+ thisData[A_INDEX] = a ?? 255;
}
return this;
}
@@ -734,11 +743,12 @@ export class Color extends ValueType implements Modifiable {
* @param other The specified color.
*/
public multiply (other: Color): Color {
+ const thisData = this._data;
// FIXME: not sure if other is really Color, so use getter.
- this._data[R_INDEX] *= other.r / 255;
- this._data[G_INDEX] *= other.g / 255;
- this._data[B_INDEX] *= other.b / 255;
- this._data[A_INDEX] *= other.a / 255;
+ thisData[R_INDEX] *= other.r / 255;
+ thisData[G_INDEX] *= other.g / 255;
+ thisData[B_INDEX] *= other.b / 255;
+ thisData[A_INDEX] *= other.a / 255;
return this;
}