Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color: Add 'colorSpace' argument for getters/setters #23392

Merged
merged 3 commits into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions docs/api/en/math/Color.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,13 @@ <h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param
Sets this color's components from the [page:BufferAttribute attribute].
</p>

<h3>[method:Integer getHex]()</h3>
<h3>[method:Integer getHex]( [param:string colorSpace] = SRGBColorSpace )</h3>
<p>Returns the hexadecimal value of this color.</p>

<h3>[method:String getHexString]()</h3>
<h3>[method:String getHexString]( [param:string colorSpace] = SRGBColorSpace )</h3>
<p>Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').</p>

<h3>[method:Object getHSL]( [param:Object target] )</h3>
<h3>[method:Object getHSL]( [param:Object target], [param:string colorSpace] = LinearSRGBColorSpace )</h3>
<p>
[page:Object target] — the result will be copied into this Object. Adds h, s and l keys to the object (if not already present).<br /><br />

Expand All @@ -180,7 +180,7 @@ <h3>[method:Object getHSL]( [param:Object target] )</h3>

</p>

<h3>[method:String getStyle]()</h3>
<h3>[method:String getStyle]( [param:string colorSpace] = SRGBColorSpace )</h3>
<p>Returns the value of this color as a CSS style string. Example: 'rgb(255,0,0)'.</p>

<h3>[method:this lerp]( [param:Color color], [param:Float alpha] ) </h3>
Expand Down Expand Up @@ -237,14 +237,14 @@ <h3>[method:this set]( [param:Color_Hex_or_String value] ) </h3>
Delegates to [page:.copy], [page:.setStyle], or [page:.setHex] depending on input type.
</p>

<h3>[method:this setHex]( [param:Integer hex] ) </h3>
<h3>[method:this setHex]( [param:Integer hex], [param:string colorSpace] = SRGBColorSpace ) </h3>
<p>
[page:Integer hex] — [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] format.<br /><br />

Sets this color from a hexadecimal value.
</p>

<h3>[method:this setHSL]( [param:Float h], [param:Float s], [param:Float l] ) </h3>
<h3>[method:this setHSL]( [param:Float h], [param:Float s], [param:Float l], [param:string colorSpace] = LinearSRGBColorSpace ) </h3>
<p>
[page:Float h] — hue value between 0.0 and 1.0 <br />
[page:Float s] — saturation value between 0.0 and 1.0 <br />
Expand All @@ -253,7 +253,7 @@ <h3>[method:this setHSL]( [param:Float h], [param:Float s], [param:Float l] ) </
Sets color from HSL values.
</p>

<h3>[method:this setRGB]( [param:Float r], [param:Float g], [param:Float b] ) </h3>
<h3>[method:this setRGB]( [param:Float r], [param:Float g], [param:Float b], [param:string colorSpace] = LinearSRGBColorSpace ) </h3>
<p>
[page:Float r] — Red channel value between 0.0 and 1.0.<br />
[page:Float g] — Green channel value between 0.0 and 1.0.<br />
Expand All @@ -269,7 +269,7 @@ <h3>[method:this setScalar]( [param:Float scalar] ) </h3>
Sets all three color components to the value [page:Float scalar].
</p>

<h3>[method:this setStyle]( [param:String style] ) </h3>
<h3>[method:this setStyle]( [param:String style], [param:string colorSpace] = SRGBColorSpace ) </h3>
<p>
[page:String style] — color as a CSS-style string.<br /><br />

Expand All @@ -288,7 +288,7 @@ <h3>[method:this setStyle]( [param:String style] ) </h3>
Note that for X11 color names, multiple words such as Dark Orange become the string 'darkorange'.
</p>

<h3>[method:this setColorName]( [param:String style] ) </h3>
<h3>[method:this setColorName]( [param:String style], [param:string colorSpace] = SRGBColorSpace ) </h3>
<p>
[page:String style] — color name ( from [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart X11 color names] ).<br /><br />

Expand Down
18 changes: 9 additions & 9 deletions docs/api/zh/math/Color.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,13 @@ <h3>[method:this fromBufferAttribute]( [param:BufferAttribute attribute], [param
根据参数 [page:BufferAttribute attribute] 设置该颜色。
</p>

<h3>[method:Integer getHex]()</h3>
<h3>[method:Integer getHex]( [param:string colorSpace] = SRGBColorSpace )</h3>
<p>返回此颜色的十六进制值。</p>

<h3>[method:String getHexString]()</h3>
<h3>[method:String getHexString]( [param:string colorSpace] = SRGBColorSpace )</h3>
<p>将此颜色的十六进制值作为字符串返回 (例如, 'FFFFFF')。</p>

<h3>[method:Object getHSL]( [param:Object target] )</h3>
<h3>[method:Object getHSL]( [param:Object target], [param:string colorSpace] = LinearSRGBColorSpace )</h3>
<p>
[page:Object target] — 结果将复制到这个对象中。向对象添加h、s和l键(如果不存在)。<br /><br />

Expand All @@ -179,7 +179,7 @@ <h3>[method:Object getHSL]( [param:Object target] )</h3>

</p>

<h3>[method:String getStyle]()</h3>
<h3>[method:String getStyle]( [param:string colorSpace] = SRGBColorSpace )</h3>
<p>以CSS样式字符串的形式返回该颜色的值。例如:“rgb(255,0,0)”。</p>

<h3>[method:this lerp]( [param:Color color], [param:Float alpha] ) </h3>
Expand Down Expand Up @@ -231,15 +231,15 @@ <h3>[method:this set]( [param:Color_Hex_or_String value] ) </h3>
根据输入类型,将会委托给 [page:.copy], [page:.setStyle], 或者 [page:.setHex] 函数处理。
</p>

<h3>[method:this setHex]( [param:Integer hex] ) </h3>
<h3>[method:this setHex]( [param:Integer hex], [param:string colorSpace] = SRGBColorSpace ) </h3>
<p>
[page:Integer hex] — [link:https://en.wikipedia.org/wiki/Web_colors#Hex_triplet hexadecimal triplet] 格式。<br /><br />

采用十六进制值设置此颜色。

</p>

<h3>[method:this setHSL]( [param:Float h], [param:Float s], [param:Float l] ) </h3>
<h3>[method:this setHSL]( [param:Float h], [param:Float s], [param:Float l], [param:string colorSpace] = LinearSRGBColorSpace ) </h3>
<p>
[page:Float h] — 色相值处于0到1之间。hue value between 0.0 and 1.0 <br />
[page:Float s] — 饱和度值处于0到1之间。<br />
Expand All @@ -248,7 +248,7 @@ <h3>[method:this setHSL]( [param:Float h], [param:Float s], [param:Float l] ) </
采用HLS值设置此颜色。
</p>

<h3>[method:this setRGB]( [param:Float r], [param:Float g], [param:Float b] ) </h3>
<h3>[method:this setRGB]( [param:Float r], [param:Float g], [param:Float b], [param:string colorSpace] = LinearSRGBColorSpace ) </h3>
<p>
[page:Float r] — 红色通道的值在0到1之间。<br />
[page:Float g] — 绿色通道的值在0到1之间。<br />
Expand All @@ -264,7 +264,7 @@ <h3>[method:this setScalar]( [param:Float scalar] ) </h3>
将颜色的RGB值都设为该 [page:Float scalar] 的值。
</p>

<h3>[method:this setStyle]( [param:String style] ) </h3>
<h3>[method:this setStyle]( [param:String style], [param:string colorSpace] = SRGBColorSpace ) </h3>
<p>
[page:String style] — 颜色css样式的字符串<br /><br />

Expand All @@ -283,7 +283,7 @@ <h3>[method:this setStyle]( [param:String style] ) </h3>
注意,对于X11颜色名称,多个单词(如暗橙色)变成字符串“darkorange”。
</p>

<h3>[method:this setColorName]( [param:String style] ) </h3>
<h3>[method:this setColorName]( [param:String style], [param:string colorSpace] = SRGBColorSpace ) </h3>
<p>
[page:String style] — 颜色名字的英文单词 ( 具体请查阅 [link:https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart X11 color names] )<br /><br />

Expand Down
1 change: 1 addition & 0 deletions src/Three.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export { Vector3 } from './math/Vector3.js';
export { Vector2 } from './math/Vector2.js';
export { Quaternion } from './math/Quaternion.js';
export { Color } from './math/Color.js';
export { ColorManagement } from './math/ColorManagement.js';
export { SphericalHarmonics3 } from './math/SphericalHarmonics3.js';
export { SpotLightHelper } from './helpers/SpotLightHelper.js';
export { SkeletonHelper } from './helpers/SkeletonHelper.js';
Expand Down
5 changes: 5 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ export const RGBADepthPacking = 3201;
export const TangentSpaceNormalMap = 0;
export const ObjectSpaceNormalMap = 1;

// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.
export const NonColorData = '';
donmccurdy marked this conversation as resolved.
Show resolved Hide resolved
export const SRGBColorSpace = 'srgb';
export const LinearSRGBColorSpace = 'srgb-linear';

export const ZeroStencilOp = 0;
export const KeepStencilOp = 7680;
export const ReplaceStencilOp = 7681;
Expand Down
86 changes: 63 additions & 23 deletions src/math/Color.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { clamp, euclideanModulo, lerp } from './MathUtils.js';
import { ColorManagement, SRGBToLinear, LinearToSRGB } from './ColorManagement.js';
import { SRGBColorSpace, LinearSRGBColorSpace } from '../constants.js';

const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
Expand All @@ -25,6 +27,7 @@ const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua'
'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };

const _rgb = { r: 0, g: 0, b: 0 };
const _hslA = { h: 0, s: 0, l: 0 };
const _hslB = { h: 0, s: 0, l: 0 };

Expand All @@ -39,15 +42,13 @@ function hue2rgb( p, q, t ) {

}

function SRGBToLinear( c ) {
function toComponents( source, target ) {

return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
target.r = source.r;
target.g = source.g;
target.b = source.b;

}

function LinearToSRGB( c ) {

return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
return target;

}

Expand Down Expand Up @@ -96,29 +97,33 @@ class Color {

}

setHex( hex ) {
setHex( hex, colorSpace = SRGBColorSpace ) {

hex = Math.floor( hex );

this.r = ( hex >> 16 & 255 ) / 255;
this.g = ( hex >> 8 & 255 ) / 255;
this.b = ( hex & 255 ) / 255;

ColorManagement.toWorkingColorSpace( this, colorSpace );

return this;

}

setRGB( r, g, b ) {
setRGB( r, g, b, colorSpace = LinearSRGBColorSpace ) {

this.r = r;
this.g = g;
this.b = b;

ColorManagement.toWorkingColorSpace( this, colorSpace );

return this;

}

setHSL( h, s, l ) {
setHSL( h, s, l, colorSpace = LinearSRGBColorSpace ) {

// h,s,l ranges are in 0.0 - 1.0
h = euclideanModulo( h, 1 );
Expand All @@ -140,11 +145,13 @@ class Color {

}

ColorManagement.toWorkingColorSpace( this, colorSpace );

return this;

}

setStyle( style ) {
setStyle( style, colorSpace = SRGBColorSpace ) {

function handleAlpha( string ) {

Expand Down Expand Up @@ -181,6 +188,8 @@ class Color {
this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;

ColorManagement.toWorkingColorSpace( this, colorSpace );

handleAlpha( color[ 4 ] );

return this;
Expand All @@ -194,6 +203,8 @@ class Color {
this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;

ColorManagement.toWorkingColorSpace( this, colorSpace );

handleAlpha( color[ 4 ] );

return this;
Expand All @@ -214,7 +225,7 @@ class Color {

handleAlpha( color[ 4 ] );

return this.setHSL( h, s, l );
return this.setHSL( h, s, l, colorSpace );

}

Expand All @@ -236,6 +247,8 @@ class Color {
this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;

ColorManagement.toWorkingColorSpace( this, colorSpace );

return this;

} else if ( size === 6 ) {
Expand All @@ -245,6 +258,8 @@ class Color {
this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;

ColorManagement.toWorkingColorSpace( this, colorSpace );

return this;

}
Expand All @@ -253,23 +268,23 @@ class Color {

if ( style && style.length > 0 ) {

return this.setColorName( style );
return this.setColorName( style, colorSpace );

}

return this;

}

setColorName( style ) {
setColorName( style, colorSpace = SRGBColorSpace ) {

// color keywords
const hex = _colorKeywords[ style.toLowerCase() ];

if ( hex !== undefined ) {

// red
this.setHex( hex );
this.setHex( hex, colorSpace );

} else {

Expand Down Expand Up @@ -334,23 +349,27 @@ class Color {

}

getHex() {
getHex( colorSpace = SRGBColorSpace ) {

ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );

return clamp( this.r * 255, 0, 255 ) << 16 ^ clamp( this.g * 255, 0, 255 ) << 8 ^ clamp( this.b * 255, 0, 255 ) << 0;
return clamp( _rgb.r * 255, 0, 255 ) << 16 ^ clamp( _rgb.g * 255, 0, 255 ) << 8 ^ clamp( _rgb.b * 255, 0, 255 ) << 0;

}

getHexString() {
getHexString( colorSpace = SRGBColorSpace ) {

return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( - 6 );

}

getHSL( target ) {
getHSL( target, colorSpace = LinearSRGBColorSpace ) {

// h,s,l ranges are in 0.0 - 1.0

const r = this.r, g = this.g, b = this.b;
ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );

const r = _rgb.r, g = _rgb.g, b = _rgb.b;

const max = Math.max( r, g, b );
const min = Math.min( r, g, b );
Expand Down Expand Up @@ -389,9 +408,30 @@ class Color {

}

getStyle() {
getRGB( target, colorSpace = LinearSRGBColorSpace ) {

ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );

target.r = _rgb.r;
target.g = _rgb.g;
target.b = _rgb.b;

return target;

}

getStyle( colorSpace = SRGBColorSpace ) {

ColorManagement.fromWorkingColorSpace( toComponents( this, _rgb ), colorSpace );

if ( colorSpace !== SRGBColorSpace ) {

// Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
return `color(${ colorSpace } ${ _rgb.r } ${ _rgb.g } ${ _rgb.b })`;

}

return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
return `rgb(${( _rgb.r * 255 ) | 0},${( _rgb.g * 255 ) | 0},${( _rgb.b * 255 ) | 0})`;

}

Expand Down
Loading