Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3cf4991

Browse files
feat: car,setState有bug
1 parent beef9be commit 3cf4991

File tree

2 files changed

+175
-23
lines changed

2 files changed

+175
-23
lines changed

‎src/views/three/car/Car.tsx

Lines changed: 139 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useRef } from 'react'
1+
import React, { useEffect, useRef,useState } from 'react'
22
import * as THREE from 'three'
33
// 导入轨道控制器
44
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
@@ -9,7 +9,9 @@ import styles from './car.module.scss'
99
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
1010
// 导入draco解码器
1111
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
12+
import { Col, Radio, RadioChangeEvent, Row } from 'antd'
1213
const Car = () => {
14+
const [count, setCount] = useState(0)
1315
const canvasDom = useRef<HTMLDivElement>(null)
1416
// 创建场景
1517
const scene = new THREE.Scene()
@@ -47,15 +49,24 @@ const Car = () => {
4749
// 更新相机投影矩阵
4850
camera.updateProjectionMatrix()
4951
}
52+
let requestAnimation: number
5053
function render() {
51-
controller.update()
54+
controller&&controller.update()
5255
renderer.render(scene, camera)
53-
requestAnimationFrame(render)
56+
requestAnimation=window.requestAnimationFrame(render)
5457
}
5558

56-
let wheels = []
59+
let wheels: THREE.Mesh[] = []
5760
// 车身,车前脸,引擎盖,挡风玻璃
58-
let carBody, frontCar, hoodCar, glassCar
61+
let carBody: THREE.Mesh<
62+
THREE.BufferGeometry<THREE.NormalBufferAttributes>,
63+
THREE.Material | THREE.Material[],
64+
THREE.Object3DEventMap
65+
>,
66+
frontCar,
67+
hoodCar,
68+
glassCar
69+
5970
// 创建材质
6071
// 车身物理材质
6172
const bodyMaterial = new THREE.MeshPhysicalMaterial({
@@ -65,21 +76,46 @@ const Car = () => {
6576
clearcoat: 1, // 清漆
6677
clearcoatRoughness: 0 // 清漆粗糙度
6778
})
79+
80+
const frontMaterial = new THREE.MeshPhysicalMaterial({
81+
color: 0xff0000,
82+
metalness: 1, // 金属度
83+
roughness: 0.5, // 粗糙程度
84+
clearcoat: 1, // 清漆
85+
clearcoatRoughness: 0 // 清漆粗糙度
86+
})
87+
const hoodMaterial = new THREE.MeshPhysicalMaterial({
88+
color: 0xff0000,
89+
metalness: 1, // 金属度
90+
roughness: 0.5, // 粗糙程度
91+
clearcoat: 1, // 清漆
92+
clearcoatRoughness: 0 // 清漆粗糙度
93+
})
94+
const wheelsMaterial = new THREE.MeshPhysicalMaterial({
95+
color: 0xff0000,
96+
metalness: 1, // 金属度
97+
roughness: 0.1 // 粗糙程度
98+
})
99+
const glassMaterial = new THREE.MeshPhysicalMaterial({
100+
color: 0xffffff,
101+
metalness: 0,
102+
transmission: 1, // 透明度
103+
transparent: true,
104+
roughness: 0
105+
})
106+
// 初始化渲染器,渲染背景
107+
renderer.setClearColor('#000')
108+
scene.background = new THREE.Color('#ccc')
109+
render()
110+
// 添加网格地面
111+
const gridHelper = new THREE.GridHelper()
112+
gridHelper.material.opacity = 0.2
113+
gridHelper.material.transparent = true
114+
scene.add(gridHelper)
115+
// // 实例化加载器gltf
116+
68117
useEffect(() => {
69118
canvasDom.current!.appendChild(renderer.domElement)
70-
onresize()
71-
window.addEventListener('resize', onresize)
72-
// 初始化渲染器,渲染背景
73-
renderer.setClearColor('#000')
74-
scene.background = new THREE.Color('#ccc')
75-
render()
76-
// 添加网格地面
77-
const gridHelper = new THREE.GridHelper()
78-
gridHelper.material.opacity = 0.2
79-
gridHelper.material.transparent = true
80-
scene.add(gridHelper)
81-
82-
// 实例化加载器gltf
83119
const gltfLoader = new GLTFLoader()
84120
// 实例化加载器draco
85121
const dracoLoader = new DRACOLoader()
@@ -92,26 +128,31 @@ const Car = () => {
92128
'/models/bmw01.glb',
93129
// 加载完成回调
94130
(gltf) => {
95-
console.log(gltf)
96131
const bmw = gltf.scene
97132
scene.add(bmw)
98133
bmw.traverse((child) => {
99134
if ((child as THREE.Mesh)?.isMesh) {
100135
if (child.name.includes('轮毂')) {
101-
wheels.push(child)
136+
wheels.push(child as THREE.Mesh)
137+
wheels.forEach((child) => {
138+
child.material = wheelsMaterial
139+
})
102140
}
103141
if (child.name.includes('Mesh002')) {
104142
carBody = child as THREE.Mesh
105143
carBody.material = bodyMaterial
106144
}
107145
if (child.name.includes('前脸')) {
108146
frontCar = child as THREE.Mesh
147+
frontCar.material = frontMaterial
109148
}
110149
if (child.name.includes('引擎盖_1')) {
111150
hoodCar = child as THREE.Mesh
151+
hoodCar.material = hoodMaterial
112152
}
113153
if (child.name.includes('挡风玻璃')) {
114154
glassCar = child as THREE.Mesh
155+
glassCar.material = glassMaterial
115156
}
116157
}
117158
})
@@ -146,14 +187,89 @@ const Car = () => {
146187
const light9 = new THREE.DirectionalLight(0xffffff, 1)
147188
light9.position.set(-5, 10, 0)
148189
scene.add(light9)
190+
return () => {
191+
window.cancelAnimationFrame(requestAnimation)
192+
}
193+
}, [])
194+
195+
useEffect(() => {
196+
onresize()
197+
window.addEventListener('resize', onresize)
149198
return () => {
150199
window.removeEventListener('resize', onresize)
151200
}
152201
})
202+
interface GlassMaterialItem {
203+
label: string
204+
value: number
205+
}
206+
const bodyColors = ['red', 'blue', 'green', 'gray', 'orange', 'purple']
207+
const glassMaterials: GlassMaterialItem[] = [
208+
{
209+
label: '磨砂',
210+
value: 1
211+
},
212+
{
213+
label: '冰晶',
214+
value: 0
215+
}
216+
]
217+
const [currentColor, setCurrentColor] = useState('red')
218+
const [currentGlassMaterial, setCurrentGlassMaterial] = useState(0)
219+
220+
function onGlassChange(e: RadioChangeEvent) {
221+
// setCurrentGlassMaterial(e.target.value)
222+
bodyMaterial.clearcoatRoughness = e.target.value
223+
frontMaterial.clearcoatRoughness = e.target.value
224+
hoodMaterial.clearcoatRoughness = e.target.value
225+
}
226+
function onColorChange(color: string) {
227+
// setCurrentColor(color)
228+
bodyMaterial.color.set(color)
229+
frontMaterial.color.set(color)
230+
hoodMaterial.color.set(color)
231+
wheelsMaterial.color.set(color)
232+
}
153233
return (
154-
<div className="page-container">
155-
{import.meta.env.PUBLIC_URL}
156-
<div className={styles.canvasContainer} ref={canvasDom}></div>
234+
<div className="page-container" style={{ position: 'relative' }}>
235+
<div
236+
id="canvasDom"
237+
className={styles.canvasContainer}
238+
ref={canvasDom}
239+
></div>
240+
<div className={styles.selector}>
241+
<div className={styles.selectorTitle}>汽车展示与选配</div>
242+
<div className={styles.selectorTitleSecond}>选择车身颜色</div>
243+
<div className={styles.colorBox}>
244+
<Row gutter={20}>
245+
{bodyColors.map((color, index) => {
246+
return (
247+
<Col key={index}>
248+
<div
249+
onClick={() => onColorChange(color)}
250+
style={{
251+
backgroundColor: color
252+
}}
253+
className={
254+
styles.colorItem +
255+
' ' +
256+
(currentColor == color ? styles.currentColor : '')
257+
}
258+
></div>
259+
</Col>
260+
)
261+
})}
262+
</Row>
263+
</div>
264+
<div className={styles.selectorTitleSecond}>选择贴膜材质</div>
265+
<Radio.Group
266+
options={glassMaterials}
267+
onChange={onGlassChange}
268+
value={currentGlassMaterial}
269+
optionType="button"
270+
buttonStyle="solid"
271+
/>
272+
</div>
157273
</div>
158274
)
159275
}

‎src/views/three/car/car.module.scss

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,40 @@
11
.canvasContainer {
22
width: 100%;
33
height: 100%;
4+
}
5+
6+
.selector {
7+
position: absolute;
8+
right: 40px;
9+
top: 20px;
10+
line-height: 1.5;
11+
color: #333;
12+
13+
.selectorTitle {
14+
font-size: 24px;
15+
font-weight: 600;
16+
}
17+
18+
.selectorTitleSecond {
19+
font-size: 18px;
20+
font-weight: 600;
21+
margin-bottom: 20px;
22+
}
23+
24+
.colorBox {
25+
display: flex;
26+
align-items: center;
27+
margin-top: 12px;
28+
margin-bottom: 10px;
29+
}
30+
31+
.colorItem {
32+
width: 32px;
33+
height: 32px;
34+
border-radius: 8px;
35+
}
36+
37+
.currentColor {
38+
border: 2px solid #fff;
39+
}
440
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /