Javascript 如何使用画布制作无限网格?

Javascript 如何使用画布制作无限网格?,javascript,css,node.js,canvas,html5-canvas,Javascript,Css,Node.js,Canvas,Html5 Canvas,很好的示例网格可以位于以下站点:,在这里您可以 单击并围绕此网格移动。所以我想学习如何制作这样一个无止境的网格,你可以继续前进 片段: canvas=document.querySelector('.field'); ctx=canvas.getContext('2d'); canvas.width=window.screen.width; canvas.height=window.screen.height; 对于(设x=0.5;x{ //仅在注册mousedown事件时移动网格 如果(!开始

很好的示例网格可以位于以下站点:,在这里您可以 单击并围绕此网格移动。所以我想学习如何制作这样一个无止境的网格,你可以继续前进

片段:
canvas=document.querySelector('.field');
ctx=canvas.getContext('2d');
canvas.width=window.screen.width;
canvas.height=window.screen.height;
对于(设x=0.5;x
正文{
保证金:0;
填充:0;
}

无限网格

您必须处理鼠标事件,才能知道鼠标左键按下时光标移动了多少

这样做的目的是移动画布的坐标系,移动量与光标移动量相同。为了避免空白出现在我们要离开的一侧,请将网格绘制为宽和高的3倍。这样,一次“拖动”操作就无法到达网格的边缘

然后,松开按钮后,将坐标系恢复到其原始状态。所以实际上你撤销了整个动作。这对用户来说并不明显,用户会觉得网格只是停止移动并捕捉到一个好点

如果你的“世界”中有真实的内容(如康威的单元格),那么你需要跟踪你的世界坐标移动了多少,当然,这些坐标不会翻转回原始状态。要填充网格中的单元格,需要将世界坐标映射到网格坐标。我在这里没有谈到这方面,因为这与你的问题相去甚远

因此,在下面的实现中,只有网格在移动,但没有世界坐标或世界内容的概念:

let canvas=document.querySelector('.field');
设ctx=canvas.getContext('2d');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
函数绘图(){
设阶跃=10;
设left=0.5-Math.ceil(canvas.width/步长)*步长;
让top=0.5-Math.ceil(canvas.height/step)*step;
let right=2*canvas.width;
让底部=2*canvas.height;
clearRect(左、上、右-左、下-上);
ctx.beginPath();
对于(设x=左;x<右;x+=步){
ctx.移动到(x,顶部);
ctx.lineTo(x,底部);
}
对于(设y=顶部;y<底部;y+=阶跃){
ctx.moveTo(左,y);
ctx.lineTo(右,y);
}
ctx.strokeStyle=“#888”;
ctx.stroke();
}
//鼠标事件处理:
让我们开始;
const getPos=(e)=>({
x:e.clientX-canvas.offsetLeft,
y:e.clientY-canvas.offsetTop
});
常数重置=()=>{
start=null;
setTransform(1,0,0,1,0,0);//重置转换
draw();
}
canvas.addEventListener(“mousedown”,e=>{
重置();
开始=获取位置(e)
});
canvas.addEventListener(“mouseup”,重置);
canvas.addEventListener(“mouseleave”,重置);
canvas.addEventListener(“mousemove”,e=>{
//仅在注册mousedown事件时移动网格
如果(!开始)返回;
设pos=getPos(e);
//以与光标相同的方式移动坐标系
ctx.translate(pos.x-start.x,pos.y-start.y);
draw();
开始=位置;
});
draw();//页面加载时
body,html{
宽度:100%;
身高:100%;
保证金:0;
填充:0;
溢出:隐藏;
}
画布{背景:银色;}

您必须处理鼠标事件,才能知道鼠标左键按下时光标移动了多少

这样做的目的是移动画布的坐标系,移动量与光标移动量相同。为了避免空白出现在我们要离开的一侧,请将网格绘制为宽和高的3倍。这样,一次“拖动”操作就无法到达网格的边缘

然后,松开按钮后,将坐标系恢复到其原始状态。所以实际上你撤销了整个动作。这对用户来说并不明显,用户会觉得网格只是停止移动并捕捉到一个好点

如果你的“世界”中有真实的内容(如康威的单元格),那么你需要跟踪你的世界坐标移动了多少,当然,这些坐标不会翻转回原始状态。要填充网格中的单元格,需要将世界坐标映射到网格坐标。我在这里没有谈到这方面,因为这与你的问题相去甚远

因此,在下面的实现中,只有网格在移动,但没有世界坐标或世界内容的概念:

let canvas=document.querySelector('.field');
设ctx=canvas.getContext('2d');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
函数绘图(){
设阶跃=10;
设left=0.5-Math.ceil(canvas.width/步长)*步长;
让top=0.5-Math.ceil(canvas.height/step)*step;
let right=2*canvas.width;
让底部=2*canvas.height;
clearRect(左、上、右-左、下-上);
ctx.beginPath();
对于(设x=左;x<右;x+=步){
ctx.移动到(x,顶部);
ctx.lineTo(x,底部);
}
对于(设y=顶部;y<底部;y+=阶跃){
ctx.moveTo(左,y);
ctx.lineTo(右,y);
}
ctx.strokeStyle=“#888”;
ctx.stroke();
}
//鼠标事件处理:
让我们开始;
const getPos=(e)=>({
x:e.clientX-canvas.offsetLeft,
y:e.clientY-canvas.offsetTop
});
常数重置=()=>{
start=null;
setTransform(1,0,0,1,0,0);//重置转换
draw();
}
canvas.addEventListener(“mousedown”,e=>{
重置();
开始=获取位置(e)
});
canvas.addEventListener(“mouseup”,重置);
canvas.addEventListener(“mouseleave”,重置);
canvas.addEventListener(“mousemove”,e=>{
//仅在注册m时移动网格