s

使用dat.gui 控制threejs(一)

  1 import * as THREE from 'three'
  2 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'    
  3 import gsap from 'gsap'
  4 import * as dat from 'dat.gui'
  5 // Canvas
  6 const canvas = document.querySelector('canvas.webgl')
  7 
  8 // Scene
  9 const scene = new THREE.Scene()
 10 
 11 
 12 // Object
 13 const geometry = new THREE.BoxBufferGeometry(1, 1, 1, 2,2,2)
 14 // buffer  geometry  集合体是性能最佳,最gpu最友好的 geometry。  
 15 // BoxGeometry 后面三个参数设置为1, 每一面就划分为2个三角形 triangle, 2 就得到八个
 16 
 17 // 自定义一个geometry
 18 // const geometry = new THREE.BufferGeometry();
 19 // const vertices = new Float32Array([
 20 //     0,0,0,
 21 //     0,1,0,
 22 //     1,0,0
 23 // ])
 24 // geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
 25 const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe:false })
 26 const mesh = new THREE.Mesh(geometry, material)
 27 scene.add(mesh)
 28 
 29 // define a color object
 30 const obj = {
 31  color:0xff0000,
 32  spin:() => {
 33     gsap.to(mesh.rotation, {duration:1, y:mesh.rotation.y + 5})
 34  }
 35 } 
 36 
 37 /* debug gui panel*/
 38 const gui = new dat.GUI({
 39     closed: true, 
 40     // 表示一开始 panel 先处于关闭状态
 41    // width:400  设置panel width
 42 })
 43 //gui.hide() // 隐藏gui  panel
 44   
 45 gui.add(mesh.position, 'y', -3, 3, 0.01).name('positon-y') // 使用name() 重命名panel item title 
 46 gui.add(mesh.position, 'x').min(-3).max(3).step(0.01)// 用链式调用的方式也可以! 
 47 //设置控制mesh y坐标的panel Item,并且规定控制的最大值3,最小值-1, 移动步长为0.01
 48 
 49 //控制 mesh 的属性 ,比如 visible:mesh 是否可见
 50 gui.add(mesh, 'visible')
 51 gui.add(material,'wireframe')
// dat.gui 改变obj的颜色时,将材质的颜色一并替换
52 gui.addColor(obj, 'color').onChange(() => { 53 material.color.set(obj.color) 54 }) 55 gui.add(obj, 'spin') 56 // animation 57 const animations = () => { 58 gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 }) 59 gsap.to(mesh.position, { duration: 1, delay: 2, x: 0 }) 60 } 61 animations() 62 // Sizes 63 const sizes = { 64 width: window.innerWidth, 65 height: window.innerHeight 66 } 67 68 // Camera 69 const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height) 70 camera.position.z = 3 71 scene.add(camera) 72 73 // controls 74 75 const controls = new OrbitControls(camera, canvas); 76 controls.enableDamping = true 77 //开启阻尼,也就是惯性, 然后需要在每一帧进行controls.update() 78 // 79 // controls.target.y = 2 //controls target 指向的是对象围绕的焦点 80 // controls.update() 81 82 // Renderer 83 const renderer = new THREE.WebGLRenderer({ 84 canvas: canvas 85 }) 86 const tick = () => { 87 controls.update() 88 renderer.render(scene, camera) 89 window.requestAnimationFrame(tick) 90 // 动画一定需要配合帧动画请求!!! 91 } 92 tick() 93 let cursor = { 94 x:0, 95 y:0 96 } 97 // 绑定鼠标事件 98 window.addEventListener('mousemove', (event) => { 99 // 这样子会使得x,y 坐标值会归于(-0.5-0.5 这个区间), 100 cursor.x = event.clientX / sizes.width - 0.5 101 cursor.y = -(event.clientY / sizes.height - 0.5) 102 // 不加符号,会使得鼠标上下移动的时候,mesh看起来是跟随鼠标方向的,但是其实移动相机,mesh最终效果是要跟鼠标反向运动(相机向右,以相机为参照物,其实mesh向左)。 103 //camera.position.x = cursor.x 104 //camera.position.y = cursor.y 105 106 // 让相机围绕着mesh 旋转(首先要清楚 这里实现旋转,改变位置的话,是 x和z方向旋转) 107 // camera.position.x = Math.sin(cursor.x * Math.PI * 2) * 3 108 // camera.position.z = Math.cos(cursor.x * Math.PI * 2) * 3 109 // camera.position.y = cursor.y * 6 110 // camera.lookAt(mesh.position) 111 }) 112 113 //window resize handle 114 window.addEventListener('resize', () => { 115 sizes.width = window.innerWidth 116 sizes.height = window.innerHeight 117 118 camera.aspect = sizes.width / sizes.height 119 camera.updateProjectionMatrix() 120 //修改相机参数后,需要统计threejs 去更改 projectMatrix, 项目矩阵? 121 122 //renderer 修改画布的size 123 renderer.setSize(sizes.width, sizes.height) 124 renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) 125 }) 126 127 // 绑定全屏事件 128 window.addEventListener('dblclick', () => { 129 // 注意,这个特性,对于 safari 浏览器无效 130 // if(!document.fullscreenElement) { 131 // canvas.requestFullscreen() 132 // }else { 133 // document.exitFullscreen() 134 // } 135 136 //最终兼容写法 137 const fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement 138 if(!fullscreenElement) { 139 if(canvas.requestFullscreen) { 140 canvas.requestFullscreen() 141 }else if(canvas.webkitRequestFullscreen) { 142 canvas.webkitRequestFullscreen() 143 } 144 }else { 145 if(document.exitFullscreen) { 146 document.exitFullscreen() 147 }else if(document.webkitExitFullscreen) { 148 document.webkitExitFullscreen() 149 } 150 } 151 }) 152 153 renderer.setSize(sizes.width, sizes.height) 154 // 规定渲染器,设定像素比 为1 or 2 有益于性能!!! 155 renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

 

posted @ 2023-03-30 10:39  努力不搬砖的iori  阅读(104)  评论(0编辑  收藏  举报