[英]HTML5 canvas: find out if click co-ordinates are inside a given rectangle
可能有些人在這個困境中有類似的經歷,可以幫助我在這里......
基本上,我有一個canvas元素,我在其中使用循環繪制幾個矩形
context.fillRect (x, y, width, height)
現在,我希望一些矩形成為熱點並響應點擊事件。 我可以使用event.layerX
和event.layerY
點擊事件的確切(x,y)。
鑒於我知道以下內容:
如何確定點擊事件是否發生在周邊某個矩形內 ?
和,
click事件發生在哪個矩形0n?
有沒有像這樣的數學公式?
任何幫助將不勝感激,如果我不夠清楚,請告訴我......
謝謝
編輯
沒有比繞過所有矩形並檢查它們的位置和尺寸更好的方法嗎?
這是使用地圖時經常遇到的一般拓撲問題。
決定點是否在任何多邊形(矩形,圓形,不規則形狀)內的算法如下:
從被檢查的點開始構造任何方向上的任何線,直到您的多邊形所在的屏幕區域的邊緣
如果該線與奇數個位置處的任何多邊形邊界相交,則它在該多邊形內
如果該線與任何多邊形邊界相交,則它在該多邊形之外的偶數個位置。
------------ | | | o--|------------------- 1 intersection: inside | | ------------- ------------ | | o------|-----------|------------------- 2 intersections: outside | | -------------
筆記:
線的方向是無關緊要的
如果在沒有關閉的情況下在屏幕側面切割多邊形,則無法工作
如果多邊形切割自身,那么如果線恰好穿過切割點,則算法可能會失敗(例如,圖8中的線被視為單個多邊形,其中線正好穿過圖中連接的上部和下部連接處)
我討厭在這里發布大量的代碼,但是這里有一個可以幫助你的js類......
function Point(x,y){
this.x=x;
this.y=y;
}
function Polygon(){
this.points=[];
this.x_min=undefined;
this.x_max=undefined;
this.y_min=undefined;
this.y_max=undefined;
this.add = function(p){
this.points=this.points.concat(p);
if (p.x<this.x_min){this.x_min=p.x;}
if (p.x>this.x_max){this.x_max=p.x;}
if (p.y<this.y_min){this.y_min=p.y;}
if (p.y>this.y_min){this.y_max=p.y;}
}
this.pointInPoly = function(p){
var j=(this.points.length-1); //start by testing the link from the last point to the first point
var isOdd=false;
//check the bounding box conditions
if (p.x < this.x_min || p.x > this.x_max || p.y < this.y_min || p.y > this.y_max){
return false;
}
//if necessary use the line crossing algorithm
for(var i=0; i<this.points.length; i++){
if ((this.points[i].y<p.y && this.points[j].y>=p.y) ||
(this.points[j].y<p.y && this.points[i].y>=p.y)) {
if (this.points[i].x+(p.y-this.points[i].y)/(this.points[j].y-
this.points[i].y)*(this.points[j].x-this.points[i].x)<p.x)
{ isOdd=(!isOdd);} }
j=i;
}
return isOdd;
}
}
PS:您需要使用以下函數將您的點擊事件轉換為本地坐標(其中e是您的點擊事件):
function getPosition(e){
var p = new Point();
if (e.pageX != undefined && e.pageY != undefined) {
p.x = e.pageX;
p.y = e.pageY;
}
else {
p.x = e.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
p.y = e.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
p.x -= gCanvas.offsetLeft;
p.y -= gCanvas.offsetTop;
return p;
}
我最近創建了一個用於檢測矩形鼠標點擊的API。 這是非常基本的,但它應該解決你的問題
你可以在這里找到它。
注意:它目前沒有按鈕的文本支持,但它確實支持一些基本樣式
文檔: 此處代碼:
function canvasButton(x, y, w, h, style , text) {
this.style = style
this.x = x || 0;
this.y = y || 0;
this.w = w || 1;
this.h = h || 1;
this.fill = style.default.fill ;
this.text = text || undefined;
this.onclick = function() {alert("Click! Make sure to add the onclick listener to your button!")}
this.mouseup = function() {alert("Mouseup! Make sure to add the mouseup listener to your button!")}
this.addListener = function() {
var buttonX = this.x;
var buttonY = this.y;
var buttonWidth = this.w;
var buttonHeight = this.h;
var onclick = this.onclick
var mouseup = this.mouseup
var styles = this.style
var draw = this.draw
var ctx = this.ctx
this.ctx.canvas.addEventListener('mousedown',function(e){
var click_x = e.clientX;
var click_y = e.clientY;
if ( click_x >= buttonY && click_x <= buttonX + buttonWidth && click_y >= buttonY && click_y <= buttonY + buttonHeight ) {
onclick()
ctx.fillStyle = style.active.fill
ctx.fillRect(buttonX, buttonY, buttonWidth, buttonHeight);
}
})
this.ctx.canvas.addEventListener('mouseup',function(e) {
var click_x = e.clientX;
var click_y = e.clientY;
if ( click_x >= buttonY && click_x <= buttonX + buttonWidth && click_y >= buttonY && click_y <= buttonY + buttonHeight ) {
mouseup()
ctx.fillStyle = style.default.fill
ctx.fillRect(buttonX, buttonY, buttonWidth, buttonHeight);
}
})
}
}
// Draws this shape to a given context
canvasButton.prototype.draw = function(ctx) {
this.ctx = ctx
ctx.fillStyle = this.fill;
ctx.font = this.font
ctx.fillRect(this.x, this.y, this.w, this.h);
ctx.fillText(this.text,this.x,this.y)
this.addListener();
}
//Use it like this:
var start = new canvasButton(x,y,height,width,{ // Styles
"default": {
"fill":"#765",
},
"active": {
"fill":"#876",
}
})
//Event Listeners
start.mousedown = function() {
}
start.mouseup = function() {
}
start.draw(document.getElementById("canvas").getContext("2d")); // Draw to canvas
粗略地說,你可以這樣做:
var click_x = event.layerX;
var click_y = event.layerY;
for ( var i = 0; i < rects.length; i++ ) {
var rect = rects[i];
if ( click_x >= rect.x && click_x <= rect.x + rect.width
&& click_y >= rect.y && click_y <= rect.y + rect.height ) {
// The click was inside the rectange
}
}
假設我們正在處理非負寬度和高度:)
這可能有些過分,但Cake JS將完成矩形和其他形狀的工作。 看看演示 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.