Mousemove 事件不会在 canvas 上触发,即使 z-index 是最大值
Mousemove event won't fire on canvas even if z-index is max
几个星期以来我有点不知所措,试图让一个 mousemove
事件在一组分层的 canvases 上工作。
遵循早期 post, I confirmed that the event triggers properly only when the z-index
of the targeted layer is on top (as demonstrated by this simple fiddle 中的建议):
然而,在我正在使用的扩展代码中 (d3 parcoords),尽管具有与上面相同的 HTML 结构,但我无法为 [=44 触发事件=]es 在上面的平行坐标图中。
此 bl.ocks 显示了扩展版本,以及即使目标分层 canvas 具有最大 z-index
事件也无法运行的方式(尽管事件在图表下方的简单 canvas)。
我尝试从 parcoords 文件中制作一个最小示例,但鉴于互连函数的数量,无法设法获得有用且有效的版本。
我希望知道原始 parcoords 代码的人能够阐明图表的 canvases 是如何组织的,如果有什么特别的东西可能导致 mousemove
事件不上班。或者,也许一些有经验的人会发现我在我发布的示例中遗漏的一些东西。
非常感谢任何提示!
从 d3.parcoords.js 中提取代码生成 canvases:
var pc = function(selection) {
selection = pc.selection = d3.select(selection);
__.width = selection[0][0].clientWidth;
__.height = selection[0][0].clientHeight;
// canvas data layers
["marks", "foreground", "brushed", "highlight", "clickable_colors"].forEach(function(layer, i) {
canvas[layer] = selection
.append("canvas")
.attr({
id: layer, //added an id for easier selecting for mouse event
class: layer,
style: "position:absolute;z-index: " + i
})[0][0];
ctx[layer] = canvas[layer].getContext("2d");
});
// svg tick and brush layers
pc.svg = selection
.append("svg")
.attr("width", __.width)
.attr("height", __.height)
.style("font", "14px sans-serif")
.style("position", "absolute")
.append("svg:g")
.attr("transform", "translate(" + __.margin.left + "," + __.margin.top + ")");
return pc;
};
用于绘制正方形和设置mousemove事件的函数:
//This custom function returns polyline ID on click, based on its HEX color in the hidden canvas "clickable_colors"
//Loosely based on http://jsfiddle.net/DV9Bw/1/ and
function getPolylineID() {
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
function rgbToHex(r, g, b) {
if (r > 255 || g > 255 || b > 255)
throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16);
}
// set up some squares
var my_clickable_canvas = document.getElementById('clickable_colors');
var context = my_clickable_canvas.getContext('2d');
context.fillStyle = "rgb(255,0,0)";
context.fillRect(0, 0, 50, 50);
context.fillStyle = "rgb(0,0,255)";
context.fillRect(55, 0, 50, 50);
$("#clickable_colors").mousemove(function(e) {
//$(document).mousemove(function(e) {
//debugger;
var pos = findPos(this);
var x = e.pageX - pos.x;
//console.log(x)
var y = e.pageY - pos.y;
var coord = "x=" + x + ", y=" + y;
var c = this.getContext('2d');
var p = c.getImageData(x, y, 1, 1).data;
var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
$('#status').html(coord + "<br>" + hex);
console.log("Polyline's hex:" + hex)
});
}
svg 覆盖了您的画布。
canvas 和 svg 都在同一层,但是你没有在 svg 上设置 z-index,因为它是在所有 canvas 之后渲染的。
只需将 z-index: 0;
放在您链接的页面中的 svg 上,即可在 Chrome 中为我修复它。
这似乎只是 z-indexes 的问题。
您应该在所有画布和同一级别的 sgv 上同时设置 css position
和 z-index
。
编辑
抱歉,我错了,它只是 z-index。
我可以通过删除以下 css 来让它工作。
.parcoords > canvas {
pointer-events: none;
}
但这似乎在您正在使用的库中,所以只需覆盖它即可。
.parcoords > canvas {
pointer-events: auto;
}
几个星期以来我有点不知所措,试图让一个 mousemove
事件在一组分层的 canvases 上工作。
遵循早期 post, I confirmed that the event triggers properly only when the z-index
of the targeted layer is on top (as demonstrated by this simple fiddle 中的建议):
然而,在我正在使用的扩展代码中 (d3 parcoords),尽管具有与上面相同的 HTML 结构,但我无法为 [=44 触发事件=]es 在上面的平行坐标图中。
此 bl.ocks 显示了扩展版本,以及即使目标分层 canvas 具有最大 z-index
事件也无法运行的方式(尽管事件在图表下方的简单 canvas)。
我尝试从 parcoords 文件中制作一个最小示例,但鉴于互连函数的数量,无法设法获得有用且有效的版本。
我希望知道原始 parcoords 代码的人能够阐明图表的 canvases 是如何组织的,如果有什么特别的东西可能导致 mousemove
事件不上班。或者,也许一些有经验的人会发现我在我发布的示例中遗漏的一些东西。
非常感谢任何提示!
从 d3.parcoords.js 中提取代码生成 canvases:
var pc = function(selection) {
selection = pc.selection = d3.select(selection);
__.width = selection[0][0].clientWidth;
__.height = selection[0][0].clientHeight;
// canvas data layers
["marks", "foreground", "brushed", "highlight", "clickable_colors"].forEach(function(layer, i) {
canvas[layer] = selection
.append("canvas")
.attr({
id: layer, //added an id for easier selecting for mouse event
class: layer,
style: "position:absolute;z-index: " + i
})[0][0];
ctx[layer] = canvas[layer].getContext("2d");
});
// svg tick and brush layers
pc.svg = selection
.append("svg")
.attr("width", __.width)
.attr("height", __.height)
.style("font", "14px sans-serif")
.style("position", "absolute")
.append("svg:g")
.attr("transform", "translate(" + __.margin.left + "," + __.margin.top + ")");
return pc;
};
用于绘制正方形和设置mousemove事件的函数:
//This custom function returns polyline ID on click, based on its HEX color in the hidden canvas "clickable_colors"
//Loosely based on http://jsfiddle.net/DV9Bw/1/ and
function getPolylineID() {
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
function rgbToHex(r, g, b) {
if (r > 255 || g > 255 || b > 255)
throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16);
}
// set up some squares
var my_clickable_canvas = document.getElementById('clickable_colors');
var context = my_clickable_canvas.getContext('2d');
context.fillStyle = "rgb(255,0,0)";
context.fillRect(0, 0, 50, 50);
context.fillStyle = "rgb(0,0,255)";
context.fillRect(55, 0, 50, 50);
$("#clickable_colors").mousemove(function(e) {
//$(document).mousemove(function(e) {
//debugger;
var pos = findPos(this);
var x = e.pageX - pos.x;
//console.log(x)
var y = e.pageY - pos.y;
var coord = "x=" + x + ", y=" + y;
var c = this.getContext('2d');
var p = c.getImageData(x, y, 1, 1).data;
var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
$('#status').html(coord + "<br>" + hex);
console.log("Polyline's hex:" + hex)
});
}
svg 覆盖了您的画布。
canvas 和 svg 都在同一层,但是你没有在 svg 上设置 z-index,因为它是在所有 canvas 之后渲染的。
只需将 z-index: 0;
放在您链接的页面中的 svg 上,即可在 Chrome 中为我修复它。
这似乎只是 z-indexes 的问题。
您应该在所有画布和同一级别的 sgv 上同时设置 css position
和 z-index
。
编辑
抱歉,我错了,它只是 z-index。
我可以通过删除以下 css 来让它工作。
.parcoords > canvas {
pointer-events: none;
}
但这似乎在您正在使用的库中,所以只需覆盖它即可。
.parcoords > canvas {
pointer-events: auto;
}