返回

畅游3D建模新境界:自定义房间编辑工具指南(一)——画线成墙

前端

1. Canvas上的画笔:勾勒3D房间的轮廓

进入3D建模的世界,离不开Canvas画布的魔法。在这里,我们将使用Canvas作为画板,通过鼠标的灵动,描绘出未来3D房间的轮廓。Canvas的坐标体系,以左上角为默认的(0,0)点,而three.js中的坐标则与相机紧密相关,通常是y轴向上的3D坐标。当您点击生成3D时,Canvas中存储的线段数据将被转换,成为three.js坐标系中的点数据,从而构建出3D房间的框架。

1.1 点亮Canvas画布

首先,我们需要为Canvas画布注入生命,使其成为我们构思房间轮廓的舞台。使用原生JavaScript或第三方库(如Fabric.js)创建Canvas元素,赋予其独特的ID。在这个舞台上,我们先画出房间的外围轮廓,为后续的3D建模奠定基础。

// 创建Canvas元素
const canvas = document.createElement('canvas');
canvas.id = 'canvas';

// 获取Canvas画布上下文
const ctx = canvas.getContext('2d');

// 设置画布的宽高
canvas.width = 600;
canvas.height = 600;

1.2 挥洒鼠标,描绘房间轮廓

Canvas画布已经准备就绪,接下来是发挥您艺术天分的时刻了。拿起鼠标,在Canvas上自由勾勒,描绘出房间的外围轮廓。我们使用鼠标的坐标,来确定每条线段的起点和终点。

// 鼠标按下事件
canvas.addEventListener('mousedown', (e) => {
  // 获取鼠标按下时的坐标
  const x = e.clientX - canvas.offsetLeft;
  const y = e.clientY - canvas.offsetTop;

  // 标记鼠标按下的点为线段的起点
  ctx.beginPath();
  ctx.moveTo(x, y);
});

// 鼠标移动事件
canvas.addEventListener('mousemove', (e) => {
  // 获取鼠标移动时的坐标
  const x = e.clientX - canvas.offsetLeft;
  const y = e.clientY - canvas.offsetTop;

  // 如果鼠标按下,则绘制线段
  if (ctx.isPointInPath(x, y)) {
    // 绘制从起点到鼠标移动时的坐标的线段
    ctx.lineTo(x, y);
    ctx.stroke();
  }
});

// 鼠标抬起事件
canvas.addEventListener('mouseup', () => {
  // 标记鼠标抬起时,线段绘制完成
  ctx.closePath();
});

1.3 保存线段数据,准备3D建模

当您完成房间外围轮廓的绘制后,我们需要将Canvas画布中储存的线段数据保存起来,为后续的3D建模做准备。

// 获取Canvas画布中的线段数据
const lineData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;

// 提取线段数据中的点数据
const points = [];
for (let i = 0; i < lineData.length; i += 4) {
  // 如果该像素点是黑色(即线段的一部分)
  if (lineData[i] === 0 && lineData[i + 1] === 0 && lineData[i + 2] === 0) {
    // 将像素点的坐标保存为点数据
    points.push({ x: i / 4 % canvas.width, y: Math.floor(i / 4 / canvas.width) });
  }
}

// 将点数据存储起来
localStorage.setItem('lineData', JSON.stringify(points));

至此,我们已经完成了自定义房间编辑工具的第一步:在Canvas画布上勾勒出房间的轮廓,并保存了线段数据。敬请期待系列文章的后续部分,我们将深入探索如何将这些线段数据转换为three.js中的点数据,从而构建出完整的3D房间模型。