上节画了电脑的场景:

这节把桌面部分画一下。
我们要求能点击、滚动,可以做和网页一样的交互。
这种就只能用 CSS3DRenderer 了。
我们先引入下 CSS3DRenderer:
现在不直接把 WebGL 渲染的 canvas 元素挂载到 dom 了:

而是和 CSS3DRenderer 的 dom 一起:

const css3Renderer = new CSS3DRenderer();
css3Renderer.setSize(width, height);
const div = document.createElement('div');
div.style.position = 'relative';
div.appendChild(css3Renderer.domElement);
css3Renderer.domElement.style.position = 'absolute';
css3Renderer.domElement.style.left = '0px';
css3Renderer.domElement.style.top = '0px';
css3Renderer.domElement.style.pointerEvents = 'none';
div.appendChild(renderer.domElement);
document.body.appendChild(div);
CSS3DRenderer 的 dom 在上面,所以要用绝对定位。
然后它也一样要每帧渲染:

css3Renderer.render(scene, camera);
之后我们把显示器的内容画一下:


<div id="desktop"></div>
#desktop {
width: 500px;
height: 500px;
background: pink;
}
然后把它加到显示器上:
先找下桌面位置:

打印下所有网格模型:
if(obj.isMesh) {
console.log(obj.name, obj);
}

分别改下颜色试试:

if(obj.name === 'Object_4') {
obj.material.color.set('orange');
}


排除 Object_4、Object_7,那剩下的 Object_5 就是桌面了。
我们加一下局部坐标系:

if(obj.name === 'Object_5') {
const helper = new THREE.AxesHelper(1000);
obj.add(helper);
}

位置正好在桌面中央。
那直接把 CSS3DObject 加到这个对象下么?
试一下:

const ele = document.getElementById('desktop');
const css3dObj = new CSS3DObject(ele);
obj.add(css3dObj);

可以看到,明显太大了。
这是因为外面有个 scale:

会把所有子对象一起放大。

css3dObj.rotateX(-Math.PI / 2);
css3dObj.scale.set(0.01,0.01,0.01);
旋转一下,然后缩小 100 倍。
这样放大后就是比较合适的大小了。

然后它的位置还要在 y 轴移动一段距离:


因为放大 100 倍,移动 2 就是 200。
css3dObj.position.y = 2;

刚刚好。
我们设置下背面隐藏:

backface-visibility: hidden;



大小正好,x 轴方向位置需要移动一下。

css3dObj.position.x = -0.16;

CSS3DObject 的位置确定好了,接下来就可以填充网页内容了。
案例代码上传了小册仓库
总结
这节我们加上了 CSS3DRenderer。
我们给桌面上加了一个 CSS3DObject,用 html 来渲染内容。
要注意的是整体放大了几百倍,那内容想要大小合适就需要缩小。
我们找到了桌面的对象,添加了一个局部坐标系 AxesHelper,这样调整位置就方便多了。
下节我们继续来填充桌面的内容。