弧上两点之间的极限值?

Limit values between two points on an arc?

我正在尝试改编 previous question on circular dial controls 中的代码。这个概念与这个非常相似,除了我想定义一个无法选择表盘的范围。考虑硬件中的体积controls/dials;他们经常有这些 'dead zones' 无法转动的地方:

如何在 JavaScript 中复制它?这是到目前为止的改编代码:

function Dial(size) {
    var dial = this;
    var canvas = document.querySelector('#c');
    var ctx = canvas.getContext("2d");
    var pi2 = Math.PI*2;

    this.from = 0.75 * Math.PI;
    this.to = 0.25 * Math.PI;
    this.value = this.from;

    var radius = size / 2 - 10;

    this.draw = function() {
        ctx.save();
        ctx.clearRect(0,0,size,size);
        ctx.translate(size/2,size/2);

        ctx.beginPath();
        ctx.strokeStyle = "silver";
        ctx.lineWidth = 2;
        ctx.arc(0, 0, radius, this.from, this.to);
        ctx.stroke();

        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.fillStyle = "green";
        ctx.strokeStyle = "black";
        ctx.arc(-radius*Math.sin(this.value),
                -radius*Math.cos(this.value),
                8, 0, 2*Math.PI);
        ctx.fill();
        ctx.stroke();
        
        ctx.restore();
    };

    var getMousePos = function(canvas, evt) {
        return {
            x: event.pageX - canvas.offsetLeft,
            y: event.pageY - canvas.offsetTop
        };
    };

    var inBounds = function(pos) {
        return Math.hypot(
            size / 2 - radius * Math.sin(dial.value) - pos.x,
            size / 2 - radius * Math.cos(dial.value) - pos.y
        ) <= 8;
    };

    canvas.addEventListener("mousemove", function(evt) {
        var pos = getMousePos(canvas, evt);
        if (dial.markerMoving) {
            if (pos.x == size/2 && pos.y == size/2)
                return;
            dial.value = Math.atan2(size/2-pos.x,size/2-pos.y);
        }
        dial.draw();
    }, false);

    canvas.addEventListener("mousedown", function(evt) {
        var pos = getMousePos(canvas, evt);
        dial.markerMoving = inBounds(pos);
    }, false);

    canvas.addEventListener("mouseup", function(evt) {
        dial.markerMoving = false;
    }, false);

    this.draw();
};

new Dial(150);
<canvas id="c"></canvas>

如果您能弄清楚如何在选择上显示 'range' - 从刻度盘上的起点到选择点,则加分。

事实证明它非常简单,使用 Math.abs

function Dial(size) {
    var dial = this;
    var canvas = document.querySelector('#c');
    var ctx = canvas.getContext("2d");
    var pi2 = Math.PI*2;

    this.from = 0.75 * Math.PI;
    this.to = 0.25 * Math.PI;
    this.value = this.from;

    var radius = size / 2 - 10;

    this.draw = function() {
        ctx.save();
        ctx.clearRect(0,0,size,size);
        ctx.translate(size/2,size/2);

        ctx.beginPath();
        ctx.strokeStyle = "silver";
        ctx.lineWidth = 2;
        ctx.arc(0, 0, radius, this.from, this.to);
        ctx.stroke();

        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.fillStyle = "green";
        ctx.strokeStyle = "black";
        ctx.arc(-radius*Math.sin(this.value),
                -radius*Math.cos(this.value),
                8, 0, 2*Math.PI);
        ctx.fill();
        ctx.stroke();
        
        ctx.restore();
    };

    var getMousePos = function(canvas, evt) {
        return {
            x: event.pageX - canvas.offsetLeft,
            y: event.pageY - canvas.offsetTop
        };
    };

    var inBounds = function(pos) {
        return Math.hypot(
            size / 2 - radius * Math.sin(dial.value) - pos.x,
            size / 2 - radius * Math.cos(dial.value) - pos.y
        ) <= 8;
    };

    canvas.addEventListener("mousemove", function(evt) {
        var pos = getMousePos(canvas, evt);
        if (dial.markerMoving) {
            if (pos.x == size/2 && pos.y == size/2) {
                return;
            }
            var radians = Math.atan2(size/2-pos.x,size/2-pos.y);
            if (Math.abs(radians) < dial.from) {
                dial.value = radians;
                dial.draw();
            }
        }
    }, false);

    canvas.addEventListener("mousedown", function(evt) {
        var pos = getMousePos(canvas, evt);
        dial.markerMoving = inBounds(pos);
    }, false);

    canvas.addEventListener("mouseup", function(evt) {
        dial.markerMoving = false;
    }, false);

    this.draw();
};

new Dial(150);
<canvas id="c"></canvas>