我正在尝试完成正在 this site 上演示的正在进行的实验。我想通过鼠标点击选择块。作为一个Javascript新手,我不知道从哪里开始这样的事情。将HTML canvas元素添加到混合中(因为它越来越受欢迎并且非常擅长操纵像素)将是一个非常好的补充。另外,如果某些块无法被选中(可能已经变灰),如果已经选择了它们的坐标,我会喜欢它。
我希望我已经清楚了。有人可以帮助我吗?有人能指出我正确的方向吗?
由于-一百万! 多德-Dastic
答案 0 :(得分:1)
您使用
id=context.getImageData(x, y, w, h);
//id.data is an array of the format [r, g, b, a, r, g, b, a]
然后使用context.putImageData(id,x,y);
我已经在诸如使用canvas的粒子效果[其中粒子是1x1像素大],我的简单3d渲染,颜色选择器等的地方应用了这个。
它很有帮助。
---更新:没有意识到你在询问有关遍历DOM树的问题......
--- ------下面的代码将找到已被点击的DOM元素。请注意,对于document.body的直接子节点的文本节点,您必须在它们周围包装一种或某种类型的容器。这是因为它们没有与element_nodes完全相同的属性...对于类似网格的效果,扩展它非常容易。一旦获得命中对象的x / y,就可以进行绘图。顺便说一句,对于您的情况,一次设置一个像素可能不是您可以做的最好的事情。我建议您查看context.fillStyle="#RRGGBB"; context.fillRect(x, y, w, h);
,在您的示例中,context.fillStyle="#0000FF"; context.fillRect(x, y, 100, 100);
...
<html>
<head>
<script>
function Rect(x, y, w, h)
{
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.hitTest = function(x, y)
{
if(this.x > x) return false; //If LEFT BORDER is right of x, fail
if(this.x + this.w < x) return false; //IF RIGHT BORDER is LEFT of x, fail
if(this.y > y) return false; //IF MY TOP IS BELOW y, fail
if(this.y + this.h < y) return false;//if my BOTTOM is above y, fail
return true;
}
};
//original: http://www.quirksmode.org/js/findpos.html
//Func was changed a little
function findPos(obj) {
var curleft = curtop = 0;
try
{
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
}catch(e){}; //Sometimes offset parent isn't Assumedined... so we just stop and return
return [curleft,curtop];
}
function findScreenPos(obj) {
var curleft = curtop = 0;
try
{
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop - obj.scrollTop;
} while (obj = obj.offsetParent);
}
}catch(e){}; //Sometimes offset parent isn't Assumedined... so we just stop and return
return [curleft,curtop];
}
findElementUnderMouseInNode = function(node)
{
//Note that this function excludes our canvas.
var cnl = node.childNodes.length;
for(var i = 0; i < cnl; i++)
{
var childNode = node.childNodes[i];
if((childNode.toString() != "[object Comment]") && (childNode != "[object Text]"))
{
{
var childNodePos = findScreenPos(childNode);
var pos = new Rect(childNodePos[0], childNodePos[1], childNode.offsetWidth, childNode.offsetHeight);
if(pos.hitTest(_xmouse, _ymouse))
{
var deeperNode = findElementUnderMouseInNode(childNode);
if(deeperNode == null)
return childNode;
else
return deeperNode;
}
}
}
}
return null;
};
window.onmousedown = function(e){
if(e.pageX)
{
_xmouse = e.pageX;
_ymouse = e.pageY;
}
else
{
if(typeof(event) == "undefined") return;
_xmouse = event.clientX + document.body.scrollLeft;
_ymouse = event.clientY + document.body.scrollTop;
}
var n = findElementUnderMouseInNode(document.body);
var mydiv = document.createElement("div");
mydiv.style.position = "absolute";
mydiv.style.left = findPos(n)[0] + "px";
mydiv.style.top = findPos(n)[1] + "px";
mydiv.style.width= n.offsetWidth + "px";
mydiv.style.height= n.offsetHeight + "px";
mydiv.style.border = "1px #FFFF00 solid";
mydiv.style.backgroundColor = "#FFFF00";
mydiv.style.opacity = 0.5;
document.body.appendChild(mydiv);
}
</script>
</head>
<body>
<span>asdf</span><br>
<img src="" width="100" height="100" />
<div>LOL</div>
asdf
</body>
</html>
功能的逻辑:
该函数获取元素的子节点
如果(节点不是注释节点或文本节点)并且子节点不是您的画布
搜索节点的子节点[更准确地说,选择位于DOM树边缘的元素,否则你可能会说“用户点击了document.body”]
如果childNode有一个被击中的子节点,则返回该节点,否则返回自己。
答案 1 :(得分:0)
这是一篇有趣的文章,其中包含许多可以让您开始使用逐像素操作的示例。你基本上需要创建一个数组并在你想要的级别修改它。
http://beej.us/blog/2010/02/html5s-canvas-part-ii-pixel-manipulation/