繁体   English   中英

在与鼠标事件交互的画布元素上创建碰撞区域

[英]Create a collision region on canvas elements That interacts with mouse Events

我想在画布元素周围创建一个碰撞区域,使我能够使用鼠标事件宽度 vanilla javascript 与该元素进行交互。

在这里详细说明我的问题如下:

首先,我使用 x、y、半径、beginAngle、endAngle 和颜色参数创建了一个弧段构造函数

var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

/* arc class constructor */
function ArcSegment(x, y, radius, beginAngle, endAngle, segColor) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.beginAngle = beginAngle;
    this.endAngle = endAngle;
    this.segColor = segColor;

    this.update = function() {
        this.draw();
    }

    this.draw = function(){
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, this.beginAngle, this.endAngle, false);
        ctx.lineWidth = 20;
        ctx.strokeStyle = this.segColor;
        ctx.stroke();
    }
}

其次,我添加了一些值来创建这些弧段

/* x, y, radius, startAngle, endAngle and color */

var centerX = canvas.width/2;
var centerY = canvas.height/2;

var radiuses = [
    100,
    120
];

var pi = Math.PI;
var segmentStart = [
    pi/2,
    0
];

var segmentRotation = [
    1.4*pi,
    0.2*pi
];
var segmentColors = [
    "#133046",
    "#15959F"
];

然后,我在画布上绘制它们。

var segment1 = new ArcSegment(centerX, centerY, radiuses[0], segmentStart[0], segmentStart[0]+segmentRotation[0], segmentColors[0]);
segment1.update();

var segment2 = new ArcSegment(centerX, centerY, radiuses[1], segmentStart[1], segmentStart[1]+segmentRotation[1], segmentColors[1]);
segment2.update();

结果如下:

结果

我现在想要的是一种在创建的每个弧段顶部创建碰撞检测的方法,因此当单击鼠标或在该特定弧段顶部移动鼠标时

地区

可能会发生一系列事件(例如旋转动画等......)。

我所做的所有研究都建议获取矩形的 x 和 y 值并计算鼠标位置的距离 (mouse.x, mouse.y) 和矩形的长度,但该方法不适用于具有 lineWidth 属性的圆弧段。

任何有关该主题的帮助将不胜感激。

下面是纯数学方法,这里的关键是代码是isPointInside

 // Classes function Arc(x, y, angle, arc, radius, colour, highlightColour) { this.x = x; this.y = y; this.angle = angle; this.arc = arc; this.radius = radius; this.colour = colour; this.highlightColour = highlightColour; this.highlighted = false; this.lineWidth = 20; } Arc.prototype = { isPointInside: function(x, y) { var _x = x - this.x; var _y = y - this.y; var distance = Math.sqrt(_x * _x + _y * _y); var invDistance = 1.0 / distance; var angle = Math.acos( _x * Math.cos(this.angle) * invDistance + _y * Math.sin(this.angle) * invDistance ); return distance > (this.radius - this.lineWidth/2) && distance < (this.radius + this.lineWidth/2) && angle < this.arc/2; }, render: function(ctx) { ctx.lineWidth = this.lineWidth; ctx.strokeStyle = this.highlighted ? this.highlightColour : this.colour; ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, this.angle - this.arc/2, this.angle + this.arc/2, false ); ctx.stroke(); } }; // Variables var canvas = null; var ctx = null; var arcs = []; // Functions function draw() { ctx.fillStyle = "gray"; ctx.fillRect(0, 0, 999, 999); for (var i = 0; i < arcs.length; ++i) { arcs[i].render(ctx); } } // Event Listeners function onMouseMove(e) { var bounds = canvas.getBoundingClientRect(); var x = e.clientX - bounds.left; var y = e.clientY - bounds.top; for (var i = 0; i < arcs.length; ++i) { arcs[i].highlighted = arcs[i].isPointInside(x, y); } draw(); } // Entry Point onload = function() { canvas = document.getElementById("canvas"); canvas.onmousemove = onMouseMove; ctx = canvas.getContext("2d"); arcs.push(new Arc(190, 75, 0.2, 1.8, 60, "blue", "lime")); arcs.push(new Arc(90, 75, 3.5, 4.2, 60, "red", "lime")); draw(); }
 <canvas id="canvas"></canvas>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM