Three.js+TypeScript+Webpack学习记录(二)

使用环境参考

Node.js v16.19.1

正文

跟着文档画个线

看看 Three 的官方文档,起步 -> 画线 -> 没了?!!

不管怎么说,先画个线吧。

import * as THREE from 'three'

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const points = []
points.push(new THREE.Vector3(-1, 0, 0))
points.push(new THREE.Vector3(0, 1, 0))
points.push(new THREE.Vector3(1, 0, 0))

// 根据三个点,构建一个形状
const geometry = new THREE.BufferGeometry().setFromPoints(points)
// 红色的线材质
const material = new THREE.LineBasicMaterial({ color: 'red' })
const line = new THREE.Line(geometry, material)
scene.add(line)

// 改变摄像机的位置,离物体远点
camera.position.z = 5

const animate = () => {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()

window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})

然后执行 npm run start

模型展示

事实上在项目中基本用不上基础点、线。最直接的还是加载模型然后显示,在官方项目里搞一个 gltf 模型出来。

这里:https://github.com/mrdoob/three.js/raw/dev/examples/models/gltf/SheenChair.glb

把资源放到 public 的 gltf 目录下

import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

const scene = new THREE.Scene()
scene.background = new THREE.Color('white')
const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 3, 5)
camera.lookAt(new THREE.Vector3(0, 0, 0))
// 环境光
const light = new THREE.AmbientLight('white', 1.5)
scene.add(light)
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const loader = new GLTFLoader()
loader.load('gltf/SheenChair.glb', (gltf) => {
console.log(gltf)
scene.add(gltf.scene)
})

const animate = () => {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()

window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})

你会发现能直接加载模型资源文件,因为 public 目录被配置到了 webpack 中的 devServer 里,开发时直接就会变成根目录。

{
devServer: {
static: path.join(__dirname, 'public'),
compress: true,
port: 9000
}
}

那打包时,会打包到 dist 目录,怎么把 public 的资源移到 dist 呢?

打包发布

安装插件 npm install copy-webpack-plugin --save-dev

然后配置一下 webpack.config.js

const path = require('path')
const TerserPlugin = require('terser-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')

module.exports = {
entry: './src/index.ts',
output: {
filename: '[name].[fullhash:7].js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
devServer: {
static: path.join(__dirname, 'public'),
compress: true,
port: 9000
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
}),
new CopyPlugin({
patterns: [
{ from: './public/gltf', to: 'gltf' }
]
})
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false
})
]
}
}

加入控制器

为了查看预览模型,可以加入轨道控制器(OrbitControls):

import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

const scene = new THREE.Scene()
scene.background = new THREE.Color('white')
const camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 3, 5)
camera.lookAt(new THREE.Vector3(0, 0, 0))
// 环境光
const light = new THREE.AmbientLight('white', 1.5)
scene.add(light)
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const controls = new OrbitControls(camera, renderer.domElement)
controls.update()

// 自动旋转
controls.autoRotate = true
// 阻尼衰减
controls.enableDamping = true

const loader = new GLTFLoader()
loader.load('gltf/SheenChair.glb', (gltf) => {
console.log(gltf)
scene.add(gltf.scene)
})

const animate = () => {
requestAnimationFrame(animate)
// 如果不开启自动旋转/阻尼衰减,可以不每帧调用
controls.update()
renderer.render(scene, camera)
}
animate()

window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})

更多文章与分享

Three 学习项目链接:https://github.com/KuoKuo666/threejs-study

个人网站:www.kuokuo666.com

2023!Day Day Up!

Three.js+TypeScript+Webpack学习记录(二)

https://www.kuokuo666.com/home/kk055.html

作者

KUOKUO众享

发布于

2023-04-22

更新于

2024-03-05

许可协议

评论