1月 20, 2020 Programming
今日收到個問題,是關於把顏色變成一段數線。這個問題令筆者想起其實光也是波段,不同的波段可以反映出不同的顏色。

在網上找了一會,原來已經有科學人實作了出來。筆者把內裏的 Javascript 代碼節錄出來。

```js
/**
 * takes wavelength in nm and returns an rgba value
 */
function wavelengthToColor(wavelength) {
	
	var r, g, b, alpha, colorSpace, wl = wavelength, gamma = 1;

	if (wl >= 380 && wl < 440) {
		r = -1 * (wl - 440) / (440 - 380);
		g = 0;
		b = 1;
	} else if (wl >= 440 && wl < 490) {
		r = 0;
		g = (wl - 440) / (490 - 440);
		b = 1;
	} else if (wl >= 490 && wl < 510) {
		r = 0;
		g = 1;
		b = -1 * (wl - 510) / (510 - 490);
	} else if (wl >= 510 && wl < 580) {
		r = (wl - 510) / (580 - 510);
		g = 1;
		b = 0;
	} else if (wl >= 580 && wl < 645) {
		r = 1;
		g = -1 * (wl - 645) / (645 - 580);
		b = 0.0;
	} else if (wl >= 645 && wl <= 780) {
		r = 1;
		g = 0;
		b = 0;
	} else {
		r = 0;
		g = 0;
		b = 0;
	}

	// intensty is lower at the edges of the visible spectrum.
	if (wl > 780 || wl < 380) {
		alpha = 0;
	} else if (wl > 700) {
		alpha = (780 - wl) / (780 - 700);
	} else if (wl < 420) {
		alpha = (wl - 380) / (420 - 380);
	} else {
		alpha = 1;
	}

	colorSpace = ['rgba(' + (r * 100) + '%,' + (g * 100) + '%,' + (b * 100) + '%, ' + alpha + ')', r, g, b, alpha]

	// colorSpace is an array with 5 elements.
	// The first element is the complete code as a string.  
	// Use colorSpace[0] as is to display the desired color.  
	// use the last four elements alone or together to access each of the individual r, g, b and a channels.  

	return colorSpace;
}
```

上面 function 是把光的波長數值變換成 HTML 格式的顏色數值。另外還會獨立輸出 RGB 及 Alpha 值。

由上面的 Code 可見,如果把 380 - 780 的數值拉一條線用 0 - 100% 包裝起來,就可以用 0 - 100 中任一數值來表示每一個不同的顏色。

```js
/**
 * get color 1 to 100
 */
function getColor(value) {
	
	// get the weight
	var weight = Math.floor(380 + ((780 - 380) / 100 * value));
	
	// return color
	return wavelengthToColor(weight);
}
```

另外在 GitHub 上有其他的實作版本,不過筆者就未有嘗試。  
https://gist.github.com/mlocati/7210513

> 參考網址 : https://scienceprimer.com/javascript-code-convert-light-wavelength-color
過去文章
2025 (9)
4 (5)
3 (1)
2 (3)
2024 (25)
11 (3)
10 (3)
9 (1)
3 (18)
2022 (6)
10 (1)
6 (2)
5 (1)
3 (1)
1 (1)
2021 (21)
11 (7)
7 (1)
6 (2)
5 (2)
4 (6)
3 (2)
2 (1)
2020 (92)
12 (1)
11 (2)
10 (4)
9 (10)
8 (5)
7 (1)
6 (3)
5 (1)
4 (4)
3 (25)
2 (7)
1 (29)
2019 (57)
12 (25)
11 (7)
9 (25)