Skip to content

110. 实战:酷家乐装修编辑器(十四)

Published:

上节修复了 2D 视图绘制的一些问题:

2025-06-26 15.52.24.gif

这节我们继续来绘制 2D 视图的门窗。

在酷家乐里面,门和床的标志如下:

image.png

我们也这样来画。

首先,需要把缺口留出来:

image.png

这里和 3D 视图还不一样,我们是从 left 到 left + win.width 来挖洞,直接挖穿:

item.windows?.forEach(async win => {
    const path = new THREE.Path();

    const { left } = win.leftBottomPosition;

    path.moveTo(left, 0);
    path.lineTo(left, item.depth);
    path.lineTo(left + win.width, item.depth);
    path.lineTo(left + win.width, 0);
    path.lineTo(left, 0);
    shape.holes.push(path);
})

看下效果:

2025-06-26 20.20.23.gif

再看下另一个户型:

2025-06-26 20.21.17.gif

也没啥问题。

然后我们在洞的位置画一个窗户标志就可以了。

image.png

我们用 PlaneGeometry 来画:

image.png

item.windows?.forEach(win => {
    const geometry = new THREE.PlaneGeometry(win.width, item.depth);
    const material = new THREE.MeshBasicMaterial({
        color: 'green',
        side: THREE.DoubleSide
    });
    const winLogo = new THREE.Mesh(geometry, material);
    wall.add(winLogo);
})

image.png

它的中心点在最左边,所以应该移动 left + win.width / 2,这样刚好把中心点移动洞的中间。

image.png

const { left } = win.leftBottomPosition;
winLogo.position.x = left + win.width / 2
winLogo.position.y = 100;

看下效果:

image.png

切换到另一个户型看下:

image.png

都没问题。

我们再用同样的方式把门的洞画出来:

image.png

item.doors?.forEach(async door => {
    const path = new THREE.Path();

    const { left } = door.leftBottomPosition;

    path.moveTo(left, 0);
    path.lineTo(left, item.depth);
    path.lineTo(left + door.width, item.depth);
    path.lineTo(left + door.width, 0);
    path.lineTo(left, 0);
    shape.holes.push(path);
})

image.png

然后加上蓝色的矩形:

image.png

item.doors?.forEach(door => {
    const { left } = door.leftBottomPosition;

    const geometry = new THREE.PlaneGeometry(door.width, item.depth);
    const material = new THREE.MeshBasicMaterial({
        color: 'blue',
        side: THREE.DoubleSide
    });
    const doorLogo = new THREE.Mesh(geometry, material);
    doorLogo.position.x = left + door.width / 2
    doorLogo.position.y = 100;
    wall.add(doorLogo);
})

image.png

image.png

当然,门窗都用矩形不好区分,我们也画一个弧形:

image.png

image.png

const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.arc(0, 0,door.width, 0, Math.PI / 2);
shape.lineTo(0, 0);

const geometry = new THREE.ShapeGeometry(shape);

image.png

形状没啥问题,但中心点在左下角,所以位置改一下:

image.png

doorLogo.position.x = left;
doorLogo.position.z = -100;

不需要再移动门宽度的一半了,并且往上移动一些距离,避免和地板重合,出现闪烁现象。

image.png

image.png

这样,门就画好了。

改下颜色、透明度:

image.png

color: '#aaa',
transparent: true,
opacity: 0.8,

image.png

image.png

没啥问题。

看下整体效果:

2025-06-26 21.27.41.gif

和 3D 视图一一对应的平面图就画好了。

这里没开启墙隐藏,不是很习惯那种功能:

image.png

后面再开。

案例代码上传了小册仓库

总结

这节我们加上了 2D 视图门窗的绘制。

首先在门窗的位置挖洞,这个洞只需要计算 left 和 win.width 就行,整个挖通。

然后在洞的位置加一个矩形 PlaneGeometry 或者 ShapeGeometry。

门窗画好后,下节我们来做尺寸标注。

评论