效果
中间两个swiper部分用dom方式实现,再将其转化成为Three中的CSS3DObject对象添加到3D场景中,
代码
- 需要创建两个场景与渲染器(普通渲染器,CSS3Render)
- 通过两个场景融合实现dom插入(这种方式会导致深度信息丢失)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./others/domSwiper/css/index.css" />
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from "./node_modules/three/build/three.module.js";
import { SwiperBox } from "./others/domSwiper/index.js";
import { OrbitControls } from "./node_modules/three/examples/jsm/controls/OrbitControls.js";
import {
CSS3DRenderer,
CSS3DObject,
} from "./node_modules/three/examples/jsm/renderers/CSS3DRenderer.js";
const { scene, camera, renderer } = initScene();
const { cssScene, cssRender } = initCss3DScene();
(() => {
main();
render();
winreSize();
})();
function main() {
// 地面
const geometry = new THREE.BoxGeometry(200, 140, 2);
const material = new THREE.MeshLambertMaterial({ color: 0x00cccc });
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(Math.PI / 2);
scene.add(mesh);
// dom元素
const swiper1 = new SwiperBox({
ele: document.createElement("div"),
});
const swiperPlane1 = new CSS3DObject(swiper1.dom);
swiperPlane1.scale.set(0.08, 0.08, 0.08);
swiperPlane1.position.set(30, 0, 20);
swiperPlane1.translateY(30);
swiperPlane1.rotateX(-Math.PI * 0.15);
const swiper2 = new SwiperBox({
ele: document.createElement("div"),
});
const swiperPlane2 = new CSS3DObject(swiper2.dom);
swiperPlane2.scale.set(0.08, 0.08, 0.08);
swiperPlane2.position.set(-30, 0, 20);
swiperPlane2.translateY(30);
swiperPlane2.rotateX(-Math.PI * 0.15);
swiper1.swipering();
swiper2.swipering();
setInterval(() => {
swiper1.swipering();
swiper2.swipering();
}, 5000);
cssScene.add(swiperPlane1);
cssScene.add(swiperPlane2);
}
function winreSize() {
window.onresize = () => {
cssRender.setSize(window.innerWidth, window.innerHeight);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
};
}
function render() {
cssRender.render(cssScene, camera);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function initCss3DScene() {
const cssScene = new THREE.Scene();
const cssRender = new CSS3DRenderer();
cssRender.setSize(window.innerWidth, window.innerHeight);
cssRender.domElement.style.position = "absolute";
cssRender.domElement.style.top = 0;
document.body.appendChild(cssRender.domElement);
const controls = new OrbitControls(camera, cssRender.domElement);
return {
cssScene,
cssRender,
};
}
function initScene() {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
70,
window.innerWidth / window.innerHeight,
1,
100000
);
camera.position.set(0, 70, 110);
const renderer = new THREE.WebGLRenderer({
antialias: true,
// alpha: true,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const light = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(light);
const controls = new OrbitControls(camera, renderer.domElement);
// scene.add(new THREE.AxesHelper(100));
return {
scene,
camera,
renderer,
};
}
</script>
</body>
</html>