Skip to content

Commit

Permalink
ColorManagement: Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
donmccurdy committed Mar 3, 2022
1 parent b559473 commit d001e49
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 41 deletions.
18 changes: 9 additions & 9 deletions docs/api/en/math/Color.html
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,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 @@ -175,7 +175,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 @@ -232,14 +232,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 @@ -248,7 +248,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 @@ -264,7 +264,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 @@ -283,7 +283,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 @@ -156,13 +156,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 @@ -174,7 +174,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 @@ -226,15 +226,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 @@ -243,7 +243,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 @@ -259,7 +259,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 @@ -278,7 +278,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 @@ -125,6 +125,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 = '';
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 * as MathUtils 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 = MathUtils.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 ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
return ( _rgb.r * 255 ) << 16 ^ ( _rgb.g * 255 ) << 8 ^ ( _rgb.b * 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

0 comments on commit d001e49

Please sign in to comment.