javascript - 制作具有可选梯度问题的 HSL 托盘
问题描述
我正在尝试制作一个颜色托盘,用户可以在其中单击渐变,它会向您显示 RGB 和 HSL 值到目前为止,我已经打印出所有色调值,现在我要做的是进行适当的显示饱和度和亮度/亮度值可以在这里看到https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Colors/Color_picker_tool
我尝试使用双嵌套循环作为生成器,例如:
function * hslGen(hue){
for(let s = 0; s < 100; s++){
for(let l = 100; l > 0; l--){
yield `hsl(${hue}, ${s}%, ${l}%)`;}
}
}
但结果看起来如下https://codepen.io/superpauly/pen/XWMQboe?editors=1010我应该使用哪个循环来显示上面示例中所示的颜色托盘?
所以我得到了生成器,其余代码如下:
const canvasContext = canvRef.current.getContext("2d");
for (let hue = 0; hue < 360; hue++) {
// Generates Hue Spectrum
canvasContext.fillStyle = "hsl(" + hue + ", 100%, 50%)";
canvasContext.fillRect(5 * hue, 0, 5, 75);
}
canvRef.current.addEventListener("click", (e) => {
data = canvasContext.getImageData(e.layerX, e.layerY, 1, 1).data;
color.rgb = `rgb( ${data[0]}, ${data[1]}, ${data[2]})`;
color.h = rgbToHue(data);
color.hsl = `hsl( ${color.h}, 100%, 50%)`;
let pixel = 0;
for (let m of hslGen(color.h)){
canvasContext.fillStyle = m; //HSL Generator string
canvasContext.fillRect(pixel+=1, 75, 1440, 500); // Here is where I try to make the gradient bu it fails.
}
谢谢你。
解决方案
您需要跟踪每个像素的 x 和 y 坐标:
import React, {
useEffect,
useRef,
useState
} from "https://cdn.skypack.dev/react@17.0.1";
import ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
console.clear();
function * hslGen(hue){
for(let l = 100; l >= 0; l--)
{
for(let s = 0; s <= 100; s++)
{
yield `hsl(${hue}, ${s}%, ${l}%)`;
}
}
}
const RGBToHex = (r, g, b) => {
r = r.toString(16);
g = g.toString(16);
b = b.toString(16);
if (r.length == 1) r = "0" + r;
if (g.length == 1) g = "0" + g;
if (b.length == 1) b = "0" + b;
return `#${r+g+b}`;
};
function rgbToHue(getImageData) {
let rgbHue = {
red: getImageData[0] / 255,
green: getImageData[1] / 255,
blue: getImageData[2] / 255
};
let maxValueKey = Object.keys(rgbHue).reduce((a, b) =>
rgbHue[a] > rgbHue[b] ? a : b
);
let maxValue = Math.max(rgbHue["red"], rgbHue["green"], rgbHue["blue"]);
let minValue = Math.min(rgbHue["red"], rgbHue["green"], rgbHue["blue"]);
let hue = 0.0;
switch (maxValueKey) {
case "red":
hue = (rgbHue["green"] - rgbHue["blue"]) / (maxValue - minValue);
break;
case "green":
hue = 2.0 + (rgbHue["blue"] - rgbHue["red"]) / (maxValue - minValue);
break;
case "blue":
hue = 4.0 + (rgbHue["red"] - rgbHue["green"]) / (maxValue - minValue);
break;
}
hue = hue * 60.0;
if (hue < 0.0) {
hue = hue + 360.0;
}
console.log("Hue in Deg: " + hue);
return hue;
}
const ColorPicker = () => {
const canvRef = useRef();
const color = { rgb: "", hsl: "",
h:0};
let [col, setCol] = useState({});
let data = 0;
useEffect(() => {
const canvasContext = canvRef.current.getContext("2d");
for (let hue = 0; hue < 360; hue++) {
canvasContext.fillStyle = "hsl(" + hue + ", 100%, 50%)";
canvasContext.fillRect(5 * hue, 0, 5, 75);
}
canvRef.current.addEventListener("click", (e) => {
data = canvasContext.getImageData(e.layerX, e.layerY, 1, 1).data;
color.rgb = `rgb( ${data[0]}, ${data[1]}, ${data[2]})`;
color.h = rgbToHue(data);
color.hsl = `hsl( ${color.h}, 100%, 50%)`;
setCol({
rgb: color.rgb,
hsl: color.hsl
});
debugger;
let x = 0,
y = 0,
pix = 3; //pixel size
console.log("Start");
for (let m of hslGen(color.h)){
canvasContext.fillStyle = m;
canvasContext.fillRect(100 + x, 175 + y, pix, pix); //Need to made this a 2d saturation, light graph
console.log(m, x, y);
x += pix;
x = x % (pix * 101);
if (!x)
y += pix;
}
console.log("End");
});
console.log(color);
}, []);
return (
<>
<canvas
ref={canvRef}
height={window.innerHeight}
width={window.innerWidth}
></canvas>
<span>HSL: {col.hsl}</span>
<span>RGB: {col.rgb}</span>
</>
);
};
ReactDOM.render(, document.getElementById("colorCanvas"));
推荐阅读
- regex - 尽管存在更多匹配项,但正则表达式匹配多个数字在字符串(单词)处停止
- javascript - 如何在触发 toggleClass 语句后修复不可见元素(burgermenu)
- javascript - 移动导航栏显示选项彼此相邻而不是彼此下方
- google-bigquery - Big Query 对于简单查询来说耗时太长
- odoo - 以多公司模式搜索产品 Odoo
- csv - 如何使用 Spark 从本地驱动程序节点读取 csv 文件?
- r - How to fill a column based on a condition using sum() for matches in r
- gradle - Gradle exec task fails with "execCommand == null!"
- powerapps - 来自 powerapps 的 ms 流中的文件系统错误
- firebase - Flutter Firebase Android/ios Google 登录错误