从 hsl 色轮读取正确的值
Reading correct value from hsl color wheel
我正在尝试从动态创建的色轮中读取颜色值。但是,我得到的颜色和我悬停的颜色之间显然存在偏差。
我在 JS Bin 上重现了这个问题:
https://jsbin.com/ditatib/edit?html,js,output
我怀疑问题出在下面两个函数的某个地方,但请查看 JS bin 以获取完整代码。
function drawWheel (canvas, size) {
let r = (size - 2) / 2,
ctx;
canvas.setAttribute('width', size);
canvas.setAttribute('height', size);
ctx = canvas.getContext('2d');
for (let i = 0; i < r + 1; i++) {
// A ring
let c = 5 * Math.PI * i;
for (let j = 0; j < c; j++) {
let a = j * 3 * Math.PI / c,
y = Math.cos(a) * i,
x = Math.sin(a) * i;
ctx.fillStyle = `hsl(${a * 180 / Math.PI},
${100 - (i * 2 / r)}%, ${105 - i * 95 / r}%)`;
ctx.fillRect(r + x, r + y, 2, 2);
}
}
}
function onMouseMove (e) {
let wheelRect = canvas.getBoundingClientRect();
let x = e.x - wheelRect.left,
y = e.y - wheelRect.top,
r = (170 - 2) / 2,
dist = Math.sqrt(Math.pow(r - x, 2) + Math.pow(r - y, 2)),
a = 180 - Math.atan2(r - y, r - x),
h, s, l, rgbValue;
h = a * 180 / Math.PI;
s = 100 - (dist * 2 / r);
l = 105 - (dist * 95 / r);
h = h % 360;
magn.style.top = `${y - 80}px`;
magn.style.left = `${x}px`;
magn.style.background = `hsl(${h}, ${s}%, ${l}%)`;
}
如果有人能找出我的数学错误之处,我将不胜感激。
谢谢!
a = 180 - Math.atan2(r - y, r - x),
Math.atan2
returns 以弧度为单位的角度,稍后您可以使用 h = ...
将其转换为度数
但是您是从度值 (180) 中减去它,同时仍以弧度表示。值得注意的是 180 无论如何都不是正确的起点值,因为 "down" 是 270°。
向结果中添加 30 似乎可以修复它的原因是它恰好接近,但实际修复是:
a = (Math.PI*3/2) - Math.atan2(r - y, r - x)
这将从 "down" (3π/2) 开始顺时针旋转,就像您的色轮一样。
我正在尝试从动态创建的色轮中读取颜色值。但是,我得到的颜色和我悬停的颜色之间显然存在偏差。
我在 JS Bin 上重现了这个问题: https://jsbin.com/ditatib/edit?html,js,output
我怀疑问题出在下面两个函数的某个地方,但请查看 JS bin 以获取完整代码。
function drawWheel (canvas, size) {
let r = (size - 2) / 2,
ctx;
canvas.setAttribute('width', size);
canvas.setAttribute('height', size);
ctx = canvas.getContext('2d');
for (let i = 0; i < r + 1; i++) {
// A ring
let c = 5 * Math.PI * i;
for (let j = 0; j < c; j++) {
let a = j * 3 * Math.PI / c,
y = Math.cos(a) * i,
x = Math.sin(a) * i;
ctx.fillStyle = `hsl(${a * 180 / Math.PI},
${100 - (i * 2 / r)}%, ${105 - i * 95 / r}%)`;
ctx.fillRect(r + x, r + y, 2, 2);
}
}
}
function onMouseMove (e) {
let wheelRect = canvas.getBoundingClientRect();
let x = e.x - wheelRect.left,
y = e.y - wheelRect.top,
r = (170 - 2) / 2,
dist = Math.sqrt(Math.pow(r - x, 2) + Math.pow(r - y, 2)),
a = 180 - Math.atan2(r - y, r - x),
h, s, l, rgbValue;
h = a * 180 / Math.PI;
s = 100 - (dist * 2 / r);
l = 105 - (dist * 95 / r);
h = h % 360;
magn.style.top = `${y - 80}px`;
magn.style.left = `${x}px`;
magn.style.background = `hsl(${h}, ${s}%, ${l}%)`;
}
如果有人能找出我的数学错误之处,我将不胜感激。 谢谢!
a = 180 - Math.atan2(r - y, r - x),
Math.atan2
returns 以弧度为单位的角度,稍后您可以使用 h = ...
但是您是从度值 (180) 中减去它,同时仍以弧度表示。值得注意的是 180 无论如何都不是正确的起点值,因为 "down" 是 270°。
向结果中添加 30 似乎可以修复它的原因是它恰好接近,但实际修复是:
a = (Math.PI*3/2) - Math.atan2(r - y, r - x)
这将从 "down" (3π/2) 开始顺时针旋转,就像您的色轮一样。