Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 查找HTML5画布(单击)事件的坐标,带边框_Javascript_Html_Css_Canvas_Dom Events - Fatal编程技术网

Javascript 查找HTML5画布(单击)事件的坐标,带边框

Javascript 查找HTML5画布(单击)事件的坐标,带边框,javascript,html,css,canvas,dom-events,Javascript,Html,Css,Canvas,Dom Events,关于如何获取画布元素上事件相对于画布本身的坐标,这里有很多关于堆栈溢出的答案。我正在使用以下解决方案(getEventPosition),它工作得很好,除了在画布中添加边框之外: /**** This solution gives me an offset equal to the border size **** when the canvas has a border. Example: **** <canvas style='border: 10px solid black; b

关于如何获取画布元素上事件相对于画布本身的坐标,这里有很多关于堆栈溢出的答案。我正在使用以下解决方案(
getEventPosition
),它工作得很好,除了在画布中添加边框之外:

/**** This solution gives me an offset equal to the border size
 **** when the canvas has a border. Example:
 **** <canvas style='border: 10px solid black; background: #333;' id='gauge_canvas' width='500' height='500'></canvas>
 ****/

// Get DOM element position on page
this.getPosition = function(obj) {
    var x = 0, y = 0;
    if (obj.offsetParent) {
        do {
            x += obj.offsetLeft;
            y += obj.offsetTop;
            obj = obj.offsetParent;
        } while (obj);
    }
    return {'x': x, 'y': y};
};

// Get mouse event position in DOM element (don't know how to use scale yet).
this.getEventPosition = function(e, obj, aux_e, scale) {

    var evt, docX, docY, pos;

    evt = (e ? e : window.event);
    if (evt.pageX || evt.pageY) {
        docX = evt.pageX;
        docY = evt.pageY;
    } else if (evt.clientX || evt.clientY) {
        docX = evt.clientX + document.body.scrollLeft +
            document.documentElement.scrollLeft;
        docY = evt.clientY + document.body.scrollTop +
            document.documentElement.scrollTop;
    }
    // This works on hammer.js
    else if (typeof aux_e !== 'undefined') {
        docX = aux_e.touches[0].x;
        docY = aux_e.touches[0].y;
    }
    pos = this.getPosition(obj);
    if (typeof scale === 'undefined') {
        scale = 1;
    }
    return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale};
};
/****此解决方案提供的偏移量等于边框大小
****当画布有边框时。例子:
**** 
****/
//获取页面上的DOM元素位置
this.getPosition=函数(obj){
变量x=0,y=0;
if(对象抵销父对象){
做{
x+=对象偏移左侧;
y+=对象偏移量;
obj=obj.offsetParent;
}while(obj);
}
返回{'x':x,'y':y};
};
//获取DOM元素中的鼠标事件位置(还不知道如何使用缩放)。
this.getEventPosition=函数(e、obj、aux_e、scale){
var evt、docX、docY、pos;
evt=(e?e:window.event);
如果(evt.pageX | | evt.pageY){
docX=evt.pageX;
docY=evt.pageY;
}else if(evt.clientX | | evt.clientY){
docX=evt.clientX+document.body.scrollLeft+
document.documentElement.scrollLeft;
docY=evt.clientY+document.body.scrollTop+
document.documentElement.scrollTop;
}
//这适用于hammer.js
else if(辅助设备的类型=‘未定义’){
docX=aux_e.touch[0].x;
docY=辅助触摸[0].y;
}
pos=此.getPosition(obj);
如果(比例类型===‘未定义’){
比例=1;
}
返回{'x':(docX-pos.x)/scale,'y':(docY-pos.y)/scale};
};
因为这段代码属于我的库,可以接受用户提供的任何画布元素,所以当用户给库一个带边框的画布时,一切都会破裂。有没有考虑到边界的解决方案?

试试这个:

this.getPosition = function(obj) {
    var x = 0, y = 0;
    if (obj.offsetParent) {
        do {
            x += obj.clientLeft;
            y += obj.clientTop;
            obj = obj.offsetParent;
        } while (obj);
    }
    return {'x': x, 'y': y};
};
clientLeft
clientTop
包括边框,但
offsetLeft
offsetTop
不包括边框

如果您不想包含其他元素,以下操作可能有效:

this.getPosition = function(obj) {
    return{'x': obj.clientLeft,
           'y': obj.clientTop};
};

这是我在最近的实验中用到的东西

var stylePaddingLeft=parseInt(document.defaultView.getComputedStyle(can,未定义)['paddingLeft'],10)| | 0;
var stylePaddingTop=parseInt(document.defaultView.getComputedStyle(can,未定义)['paddingTop'],10)| | 0;
var styleBorderLeft=parseInt(document.defaultView.getComputedStyle(can,未定义)['borderLeftWidth'],10)| | 0;
var styleBorderTop=parseInt(document.defaultView.getComputedStyle(can,未定义)['borderTopWidth'],10)| | 0;
var html=document.body.parentNode;
var htmlTop=html.offsetTop;
var htmlLeft=html.offsetLeft;
函数getMouse(e){
变量元素=can,
offsetX=0,
offsetY=0,
mx,我的;
//计算总偏移量
if(element.offsetParent!==未定义){
做{
offsetX+=element.offsetLeft;
offsetY+=element.offsetTop;
}而((element=element.offsetParent));
}
//将填充和边框样式宽度添加到偏移
//如果有位置:固定杆,也可以添加偏移
offsetX+=样式填充左+样式边界左+htmlLeft;
offsetY+=stylePaddingTop+styleBorderTop+htmlTop;
mx=e.pageX-offsetX;
my=e.pageY-offsetY;
//我们返回一个定义了x和y的简单javascript对象(散列)
返回{
x:mx,
y:我的
};
}
它适用于任何边框和填充,也适用于填充偏移HTML的对象(如stumbleupon栏)的页面。如果浏览器被缩放,它也可以工作


它似乎在触摸设备上也能正常工作。

这不仅不能解决问题,而且会将画布顶部两个h1元素的高度添加到它返回的y坐标:(@janesconference我已经编辑了我的答案,试试看。也许你可以提供一个JSFIDLE和所有代码来测试它。
var stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(can, undefined)['paddingLeft'], 10) || 0;
var stylePaddingTop = parseInt(document.defaultView.getComputedStyle(can, undefined)['paddingTop'], 10) || 0;
var styleBorderLeft = parseInt(document.defaultView.getComputedStyle(can, undefined)['borderLeftWidth'], 10) || 0;
var styleBorderTop = parseInt(document.defaultView.getComputedStyle(can, undefined)['borderTopWidth'], 10) || 0;
var html = document.body.parentNode;
var htmlTop = html.offsetTop;
var htmlLeft = html.offsetLeft;

function getMouse(e) {
    var element = can,
        offsetX = 0,
        offsetY = 0,
        mx, my;

    // Compute the total offset
    if (element.offsetParent !== undefined) {
        do {
            offsetX += element.offsetLeft;
            offsetY += element.offsetTop;
        } while ((element = element.offsetParent));
    }

    // Add padding and border style widths to offset
    // Also add the <html> offsets in case there's a position:fixed bar
    offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft;
    offsetY += stylePaddingTop + styleBorderTop + htmlTop;

    mx = e.pageX - offsetX;
    my = e.pageY - offsetY;

    // We return a simple javascript object (a hash) with x and y defined
    return {
        x: mx,
        y: my
    };
}