3.js - 运动曲线

这个球,绕着这个红色的线圈转

在这里插入图片描述

代码


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

let scene,
  camera,
  renderer,
  controls = null

let moon,
  earth = null

// 根据,一系列的点,创建曲线
let curve

const textureLoader = new THREE.TextureLoader()

const clock = new THREE.Clock()

const onWindowResize = () => {
	// 重置相机的宽高比
	camera.aspect = window.innerWidth / window.innerHeight
	// 更新相机的投影矩阵
	camera.updateProjectionMatrix()
	
	// 重置渲染器的宽高比
	renderer.setSize(window.innerWidth, window.innerHeight)
	// 更新渲染器的像素比
	renderer.setPixelRatio(window.devicePixelRatio)
}

const render = () => {
	requestAnimationFrame(render)
	
	const elapsed = clock.getElapsedTime()
	let time = (elapsed /10) % 1
	const point = curve.getPoint(time)
	// console.log('point=', point) // Vector3 {x: -10, y: 0, z: 10}
	
	// 情况一,moon绕着地球转
	// moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5)
	
	// 情况二,moon绕着咱画的线转
	moon.position.copy(point)
	
	// camera.position.copy(point)
	// camera.lookAt(earth.position)
	
	renderer.render(scene, camera)
}

const init = () => {
	const EARTH_RADIUS = 1
	const MOON_RADIUS = 0.27

	scene = new THREE.Scene()
	
	camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200)
	// camera.position.set(0, 0, 3)
	camera.position.set(0, 5, -10)
	scene.add(camera)
	
	const directionLight = new THREE.DirectionalLight(0xffffff) // 平行光
	directionLight.position.set(0, 0, 1)
	scene.add(directionLight)
	const light = new THREE.AmbientLight(0xffffff, 0.5) // 环境光
	scene.add(light)

	// 添加地球
	const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 16, 16)
	const earthMaterial = new THREE.MeshPhongMaterial({
		map: textureLoader.load('../public/assets/texture/planets/earth_atmos_2048.jpg'),
		specularMap: textureLoader.load('../public/assets/texture/planets/earth_specular_2048.jpg'),
		specular: 0x333333, // 高光部分的颜色,默认值:0x111111(深灰色)
		shininess: 5, // 高光反射效果的锐利程度,该值越大,高光区域越小且更亮。默认值为30。
		normalMap: textureLoader.load('../public/assets/texture/planets/earth_normal_2048.jpg'),
		normalScale: new THREE.Vector2(0.85, 0.85)
	})
	earth = new THREE.Mesh(earthGeometry, earthMaterial)
	scene.add(earth)
	
	// 添加月球
	const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS, 16, 16)
	const moonMaterial = new THREE.MeshPhongMaterial({
		map: textureLoader.load('../public/assets/texture/planets/moon_1024.jpg'),
		shininess: 5
	})
	moon = new THREE.Mesh(moonGeometry, moonMaterial)
	// moon.position.x = 3
	scene.add(moon)

	//-------------------------------------------------------------------------------

	// 根据,一系列的点,创建曲线【参数true:表示曲线是封闭的】
	curve = new THREE.CatmullRomCurve3([new THREE.Vector3(-10, 0, 10), new THREE.Vector3(-5, 5, 5), new THREE.Vector3(0, 0, 5), new THREE.Vector3(5, -5, 5), new THREE.Vector3(10, 0, 10)], true)
	
	// 在曲线里,使用`getPoints()`,获取51个点
	const points = curve.getPoints(600)
	// console.log('points=', points) // 一个,包含600个Vector3元素的数组
	const geometry = new THREE.BufferGeometry().setFromPoints(points)
	const material = new THREE.LineBasicMaterial({ color: 0xff0000 })
	const curveObject = new THREE.Line(geometry, material)
	scene.add(curveObject)
	
	//-------------------------------------------------------------------------------
	
	renderer = new THREE.WebGLRenderer()
	renderer.setSize(window.innerWidth, window.innerHeight)
	document.body.appendChild(renderer.domElement)
	
	controls = new OrbitControls(camera, renderer.domElement)
	controls.minDistance = 5 // 相机可以离目标对象的最小距离为5个单位(意味着,用户无法将相机拉得太近)
	controls.maxDistance = 100 // 相机可以离目标对象的最大距离为100个单位(意味着,限制了用户可以将相机拉远的最大距离)
	
	window.addEventListener('resize', onWindowResize)
}

init()
render()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值