从HSL颜色轮中读取正确的值

4
我想从动态创建的颜色选择器中读取一个颜色值,但是当前获取的颜色与我悬浮的颜色存在偏差。在JS Bin上重现了这个问题:https://jsbin.com/ditatib/edit?html,js,output。我怀疑问题出在下面两个函数中,但请查看完整的JS代码以获取更多信息。
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}%)`;
}

我希望有人能找出我数学上的错误。谢谢!


我不知道原因,希望有人能够解释,但是我通过将 h % 360 改为 (h % 360) + 30 来“修复”了这个问题。 - evolutionxbox
1个回答

2
a = 180 - Math.atan2(r - y, r - x),

Math.atan2会返回一个以弧度为单位的角度,你需要用h = ...将其转换为度数。

但是在弧度中仍然从角度值(180)中减去它。值得注意的是,180并不是正确的起点,因为“向下”是270°。

之所以添加30到结果中似乎可以解决问题,是因为它只是靠近正确答案而已,实际的修复方法是:

a = (Math.PI*3/2) - Math.atan2(r - y, r - x)

这将从“下方”开始(3π/2),并顺时针旋转,就像您的颜色轮一样。

太棒了 - 谢谢!这很有道理。我显然没有做好准备。 - vikdoro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接