跳到主要内容

一个React+ThreeJs+TS demo

ThreeJs demo

先运行起来在说

import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three";

const ThreeDemo: React.FC = () => {
const [winSize, setWinSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
// 使用useRef获取canvas元素
const canvasRef = useRef < HTMLDivElement > null;
useEffect(() => {
if (canvasRef.current) {
// 1. 摆放好相机
const camera = new THREE.PerspectiveCamera(
70,
winSize.width / winSize.height,
0.01,
10
);
camera.position.z = 1;
// 2. 创建一个场景
const scene = new THREE.Scene();
// scene.background = new THREE.Color("red");
scene.overrideMaterial = new THREE.MeshBasicMaterial({ color: "green" });
// 3. 创建一个网格模型
const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);
const material = new THREE.MeshBasicMaterial({
color: 0xff0000, //0xff0000设置材质颜色为红色
});
const mesh = new THREE.Mesh(geometry, material);
// 设置网格模型在三维空间中的位置坐标,默认是坐标原点
// mesh.position.set(0, 0, 0);
scene.add(mesh);
// 4. 创建一个渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(winSize.width, winSize.height);
// 5. 将场景和相机添加到渲染器中, 可能很多人死在了这一步。
// renderer.render(scene, camera);
// 5.1 渲染动画
renderer.setAnimationLoop(animate);
canvasRef.current.innerHTML = "";
canvasRef.current.appendChild(renderer.domElement);
// 动画循环
function animate(time: number) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera);
}
}
const handleResize = () => {
console.log("handleResize");
setWinSize({ width: window.innerWidth, height: window.innerHeight });
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, [winSize.width, winSize.height]);

return (
<div>
<div style={{ width: "100vw", height: "100vh" }} ref={canvasRef}>
Demo002
</div>
</div>
);
};

export default ThreeDemo;