先直接上代码, 由于目前vue的用户比较多,就使用vue做示例(react使用起来也是也大同小异)。
// 先引入three的库
pnpm add three --save
为了方便复用, 用class 封装一下这个方法 创建文件 photo.js
代码可以直接复制,部分three方面的基础知识后面的文章会做说明
import { WebGLRenderer, PerspectiveCamera, Scene, Mesh, MeshBasicMaterial, PlaneGeometry, TextureLoader } from 'three';
import { OrbitControls } from 'three/examples/jsm/Addons.js'
export default class Photo {
constructor(canvas) {
if(canvas.nodeName !== 'CANVAS') return console.error(`canvas容器不存在`);
this.renderer = new WebGLRenderer({canvas});// 创建渲染器 renderer
this.camera = new PerspectiveCamera(75, canvas.width / canvas.height, 0.1 ,100); //创建相机
this.scene = new Scene(); // 创建场景
this.controls = new OrbitControls(this.camera, this.renderer.domElement); // 创建控制器
this.controls.autoRotate = true;
this.controls.autoRotateSpeed = 1;
this.init();
}
init() {
const imgSrclist = ['/image1.webp', '/image2.webp','/image3.webp','/image4.webp','/image5.webp','/image6.webp']; // 加载六张图片,
imgSrclist.forEach((src, index) => {
const material = new MeshBasicMaterial({
map: new TextureLoader().load(src),
side: 2
}); // 材料
const geometry = new PlaneGeometry(1.4, 1.4) // 矩形
const mesh = new Mesh(geometry, material); // 模型
mesh.position.x = 1.4 * Math.sin((index * Math.PI) / 3); // x轴定位
mesh.position.z = 1.4 * Math.cos((index * Math.PI) / 3); // z轴定位
mesh.lookAt(0, 0, 0); //
this.scene.add(mesh)
})
this.animate();
}
animate() {
this.controls.update();
requestAnimationFrame(() => this.animate())
this.renderer.render(this.scene, this.camera)
}
}
随便找一个vue文件,在template中创建一个canvas
// template 中先新建一个 canvas
<template>
<canvas ref='canvasRef'/>
</template>
<script setup>
import {ref} from 'vue';
import Photo from 'photo.js';
const canvasRef = ref(null);
onMounted(() => {
const canvas = canvasRef.value;
new Photo(canvas);
})
<script/>
上面的代码就已经完成了一个3D相册