HTML5:从画布弧获取点击位置

发布于 2024-12-27 17:15:09 字数 557 浏览 0 评论 0原文

请参阅此 jsFiddle 帖子以获取工作弧线图;感谢 Simon Sarris 修复了我之前的问题。

我使用 KineticJS 插件来创建形状并使用事件处理程序。假设您单击了弧上的某处,并且弧知道您单击的位置(xy),那么如何使用这 2 个坐标来确定百分比?

当您单击任意位置时,总百分比始终为 100%。

Addin

为了使这个更简单,我可以做什么 (x, y) 来虚拟弯曲对象,以便 x 从 0 到最大 x

See this jsFiddle post for a working arc drawing; thanks to Simon Sarris for the fix in my previous questions.

I'm using the KineticJS plugin to create shapes and make use of event handlers. Assuming you clicked somewhere on the arc and the arc knew where you clicked (x, y), how could those 2 coordinates be used to determine a percentage?

When you click anywhere, the total percentage is always 100%.

Addin

To make this simpler, what could I do to (x, y) to virtually bend the object so that x goes from 0 to maximum x?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傲世九天 2025-01-03 17:15:09

简单的三角函数。 sin(角度) = 对边/相邻oppositey 值,adjacentx 值。所以 Math.asin((xx - x) / (yy - y)) 其中 xx 和 yy 是圆弧中心的坐标。这给出了角度,然后您可以将其除以 2 * Math.PI

我一时记不起负数会发生什么。您可能必须获取参数的 Math.abs 值,然后计算出点击位于哪个象限(使用 <> 可以轻松完成;)并为每一项添加 Math.PI / 2

Simple trigonometry. sin(angle) = opposite / adjacent. opposite is the y value and adjacent is the x value. So Math.asin((xx - x) / (yy - y)) where xx and yy are the coords of the centre of the arc. That gives you the angle, which you can then divide 2 * Math.PI by.

Off the top of my head I can't remember what happens with negative numbers. You may have to take the Math.abs value of the arguments, then work out which quadrant the click is in (easy to do by using < and >) and add Math.PI / 2 for each one.

在巴黎塔顶看东京樱花 2025-01-03 17:15:09

这包括检查鼠标是否在弧内:

// Return range is 0 to Math.PI * 2
function get_mouse_circle_angle(origin_x, origin_y, mouse_x, mouse_y) {
    var mouse_angle = Math.atan2(mouse_y - origin_y, mouse_x - origin_x);
    if (mouse_angle < 0) {
        mouse_angle = (Math.PI * 2) + mouse_angle;
    }
    return mouse_angle;
}

// Return range is [0, 1)
// 0/1 is 3 oclock
function get_mouse_circle_percent(origin_x, origin_y, mouse_x, mouse_y) {
    var mouse_angle = get_mouse_circle_angle(origin_x, origin_y, mouse_x, mouse_y);
    return mouse_angle / (2 * Math.PI);
}

function get_mouse_arc_pos(origin_x, origin_y, mouse_x, mouse_y, radius, thickness) {
    var mouse_angle = Math.atan2(mouse_y - origin_y, mouse_x - origin_x);
    if (mouse_angle < 0) {
        mouse_angle = (Math.PI * 2) + mouse_angle;
    }
    var mouse_percent = mouse_angle / (2 * Math.PI);

    var circle_edge_x = origin_x + (radius + thickness / 2) * Math.cos(mouse_angle);
    var circle_edge_y = origin_y + (radius + thickness / 2) * Math.sin(mouse_angle);

    var arc_inside_x = origin_x + (radius - thickness / 2) * Math.cos(mouse_angle);
    var arc_inside_y = origin_y + (radius - thickness / 2) * Math.sin(mouse_angle);

    var is_in_circle = true;

    if (mouse_angle <= (2 * Math.PI) * 0.25) {
        if (mouse_x > circle_edge_x || mouse_y > circle_edge_y)
            is_in_circle = false;
    }
    else if (mouse_angle <= (2 * Math.PI) * 0.5) {
        if (mouse_x < circle_edge_x || mouse_y > circle_edge_y)
            is_in_circle = false;
    }
    else if (mouse_angle <= (2 * Math.PI) * 0.75) {
        if (mouse_x < circle_edge_x || mouse_y < circle_edge_y)
            is_in_circle = false;
    }
    else {
        if (mouse_x > circle_edge_x || mouse_y < circle_edge_y)
            is_in_circle = false;
    }

    var is_in_arc = is_in_circle;
    if (is_in_circle) {
        if (mouse_angle <= (2 * Math.PI) * 0.25) {
            if (mouse_x < arc_inside_x || mouse_y < arc_inside_y)
                is_in_arc = false;
        }
        else if (mouse_angle <= (2 * Math.PI) * 0.5) {
            if (mouse_x > arc_inside_x || mouse_y < arc_inside_y)
                is_in_arc = false;
        }
        else if (mouse_angle <= (2 * Math.PI) * 0.75) {
            if (mouse_x > arc_inside_x || mouse_y > arc_inside_y)
                is_in_arc = false;
        }
        else {
            if (mouse_x < arc_inside_x || mouse_y > arc_inside_y)
                is_in_arc = false;
        }
    }

    return {
        angle: mouse_angle,
        percent: mouse_percent,
        is_in_circle: is_in_circle,
        is_in_arc: is_in_arc
    };
}

This includes a check if the mouse is inside the arc:

// Return range is 0 to Math.PI * 2
function get_mouse_circle_angle(origin_x, origin_y, mouse_x, mouse_y) {
    var mouse_angle = Math.atan2(mouse_y - origin_y, mouse_x - origin_x);
    if (mouse_angle < 0) {
        mouse_angle = (Math.PI * 2) + mouse_angle;
    }
    return mouse_angle;
}

// Return range is [0, 1)
// 0/1 is 3 oclock
function get_mouse_circle_percent(origin_x, origin_y, mouse_x, mouse_y) {
    var mouse_angle = get_mouse_circle_angle(origin_x, origin_y, mouse_x, mouse_y);
    return mouse_angle / (2 * Math.PI);
}

function get_mouse_arc_pos(origin_x, origin_y, mouse_x, mouse_y, radius, thickness) {
    var mouse_angle = Math.atan2(mouse_y - origin_y, mouse_x - origin_x);
    if (mouse_angle < 0) {
        mouse_angle = (Math.PI * 2) + mouse_angle;
    }
    var mouse_percent = mouse_angle / (2 * Math.PI);

    var circle_edge_x = origin_x + (radius + thickness / 2) * Math.cos(mouse_angle);
    var circle_edge_y = origin_y + (radius + thickness / 2) * Math.sin(mouse_angle);

    var arc_inside_x = origin_x + (radius - thickness / 2) * Math.cos(mouse_angle);
    var arc_inside_y = origin_y + (radius - thickness / 2) * Math.sin(mouse_angle);

    var is_in_circle = true;

    if (mouse_angle <= (2 * Math.PI) * 0.25) {
        if (mouse_x > circle_edge_x || mouse_y > circle_edge_y)
            is_in_circle = false;
    }
    else if (mouse_angle <= (2 * Math.PI) * 0.5) {
        if (mouse_x < circle_edge_x || mouse_y > circle_edge_y)
            is_in_circle = false;
    }
    else if (mouse_angle <= (2 * Math.PI) * 0.75) {
        if (mouse_x < circle_edge_x || mouse_y < circle_edge_y)
            is_in_circle = false;
    }
    else {
        if (mouse_x > circle_edge_x || mouse_y < circle_edge_y)
            is_in_circle = false;
    }

    var is_in_arc = is_in_circle;
    if (is_in_circle) {
        if (mouse_angle <= (2 * Math.PI) * 0.25) {
            if (mouse_x < arc_inside_x || mouse_y < arc_inside_y)
                is_in_arc = false;
        }
        else if (mouse_angle <= (2 * Math.PI) * 0.5) {
            if (mouse_x > arc_inside_x || mouse_y < arc_inside_y)
                is_in_arc = false;
        }
        else if (mouse_angle <= (2 * Math.PI) * 0.75) {
            if (mouse_x > arc_inside_x || mouse_y > arc_inside_y)
                is_in_arc = false;
        }
        else {
            if (mouse_x < arc_inside_x || mouse_y > arc_inside_y)
                is_in_arc = false;
        }
    }

    return {
        angle: mouse_angle,
        percent: mouse_percent,
        is_in_circle: is_in_circle,
        is_in_arc: is_in_arc
    };
}
决绝 2025-01-03 17:15:09

没有真正测试它,但从技术上讲,它应该可以工作:

// Where x1 and y1 should be the coordinates of the arc's center
function angle(x1, y1, x2, y2) {
    // Calculate a · b
    var nominator = x1 * x2 + y1 * y2;

    // Calculate ||a|| ||b||
    var denominator = Math.sqrt(x1*x1 + y1*y1) * Math.sqrt(x2*x2 + y2*y2);
    if (denominator == 0) return 0; // Indifinite angle

    // Return the angle
    return Math.acos(nominator / denominator);
}

// Returns a percent, might be negative
var percent = angle(0, 0, mouseX, mouseY) / (2*Math.PI);

编辑

对于负数,您可以尝试添加 1,因为它在 [-1, 1] 范围内

if (percent < 0) percent += 1;

Did not really test it, but technically, it should work:

// Where x1 and y1 should be the coordinates of the arc's center
function angle(x1, y1, x2, y2) {
    // Calculate a · b
    var nominator = x1 * x2 + y1 * y2;

    // Calculate ||a|| ||b||
    var denominator = Math.sqrt(x1*x1 + y1*y1) * Math.sqrt(x2*x2 + y2*y2);
    if (denominator == 0) return 0; // Indifinite angle

    // Return the angle
    return Math.acos(nominator / denominator);
}

// Returns a percent, might be negative
var percent = angle(0, 0, mouseX, mouseY) / (2*Math.PI);

Edit

For negative numbers you can try adding 1 since it's in [-1, 1] range

if (percent < 0) percent += 1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文