1 2import { 3 AmbientLight, 4 DirectionalLight, 5 PerspectiveCamera, 6 PointLight, 7 Scene, 8 WebGLRenderer 9} from './build/three.module.min.js' 10import { OrbitControls } from './jsm/controls/OrbitControls.js' 11 12import pointer from './pointer.js' 13export default function (params) { 14 const options = { 15 el: null, 16 canvas: null, 17 eventsEl: null, 18 width: null, 19 height: null, 20 resize: true, 21 alpha: false, 22 antialias: false, 23 orbitControls: false, 24 init () {}, 25 initCamera () {}, 26 initScene () {}, 27 afterResize () {}, 28 beforeRender () {}, 29 afterRender () {}, 30 beforeunload(){}, 31 ...params 32 } 33 34 const three = { 35 renderer: null, 36 camera: null, 37 scene: null, 38 pointer: null, 39 width: 0, 40 height: 0, 41 wWidth: 0, 42 wHeight: 0, 43 clock: { 44 startTime: 0, 45 time: 0, 46 elapsed: 0 47 }, 48 options 49 } 50 51 let render 52 53 let cameraCtrl 54 55 init() 56 return three 57 58 function init () { 59 let canvas 60 if (options.el) { 61 canvas = document.createElement('canvas') 62 options.el.appendChild(canvas) 63 } else if (options.canvas) { 64 canvas = options.canvas 65 } else { 66 throw new Error('Missing parameter : el or canvas is required') 67 } 68 69 options.init?.(three); 70 three.renderer = new WebGLRenderer({ canvas, alpha: options.alpha, antialias: options.antialias }) 71 options.initRenderer?.(three) 72 73 three.camera = new PerspectiveCamera() 74 three.camera.position.z = 50; 75 options.initCamera?.(three) 76 if (options.orbitControls) { 77 cameraCtrl = new OrbitControls(three.camera, options.eventsEl ?? three.renderer.domElement) 78 cameraCtrl.enableDamping = true 79 cameraCtrl.dampingFactor = 0.1 80 if (typeof options.orbitControls === 'object') { 81 Object.keys(options.orbitControls).forEach(key => { 82 cameraCtrl[key] = options.orbitControls[key] 83 }) 84 } 85 } 86 87 resize() 88 if (options.resize && !options.width && !options.height) { 89 window.addEventListener('resize', resize) 90 } 91 92 three.scene = new Scene() 93 options.initScene?.(three) 94 95 initPointer() 96 97 render = options.render ? options.render : () => { three.renderer.render(three.scene, three.camera) } 98 99 options.beforeunload?.(three) 100 // requestAnimationFrame(timestamp => { 101 // three.clock.startTime = three.clock.time = timestamp 102 // requestAnimationFrame(animate) 103 // }) 104 animate(); 105 options.afterRender?.(three) 106 } 107 function initPointer () { 108 const pointerOptions = {} 109 if (options.onPointerEnter) { pointerOptions.onEnter = options.onPointerEnter } 110 if (options.onPointerMove) { pointerOptions.onMove = options.onPointerMove } 111 if (options.onPointerMove) { pointerOptions.onLeave = options.onPointerLeave } 112 if (Object.keys(pointerOptions).length > 0) { 113 three.pointer = pointer({ domElement: options.eventsEl ?? (options.el ?? options.canvas), ...pointerOptions }) 114 } 115 } 116 117 function animate (timestamp) { 118 const { clock } = three 119 clock.elapsed = timestamp - clock.time 120 clock.time = timestamp 121 122 options.beforeRender(three) 123 124 if (cameraCtrl) cameraCtrl.update() 125 126 render(three) 127 three.animationId = requestAnimationFrame(animate); 128 } 129 130 function resize () { 131 if (options.width && options.height) { 132 three.width = options.width 133 three.height = options.height 134 } else if (options.resize === 'window') { 135 three.width = window.innerWidth 136 three.height = window.innerHeight 137 } else { 138 const parent = three.renderer.domElement.parentElement 139 three.width = parent.clientWidth 140 three.height = parent.clientHeight 141 } 142 143 three.renderer.setSize(three.width, three.height) 144 three.camera.aspect = three.width / three.height 145 three.camera.updateProjectionMatrix() 146 if (three.camera instanceof PerspectiveCamera) { 147 const wsize = getCameraViewSize() 148 three.wWidth = wsize[0]; three.wHeight = wsize[1] 149 } else { 150 three.wWidth = three.camera.top - three.camera.bottom 151 three.wHeight = three.camera.right - three.camera.left 152 } 153 options.afterResize?.(three) 154 } 155 156 function getCameraViewSize () { 157 const vFOV = (three.camera.fov * Math.PI) / 180 158 const h = 2 * Math.tan(vFOV / 2) * Math.abs(three.camera.position.z) 159 const w = h * three.camera.aspect 160 return [w, h] 161 } 162} 163export function commonConfig (params) { 164 const config = {} 165 const keys = ['el', 'canvas', 'eventsEl', 'width', 'height', 'resize', 'orbitControls'] 166 keys.forEach(key => { 167 if (params[key] !== undefined) config[key] = params[key] 168 }) 169 return config 170} 171 172export function initLights (scene, lightsConfig) { 173 const lights = [] 174 if (Array.isArray(lightsConfig) && lightsConfig.length > 0) { 175 let light 176 lightsConfig.forEach(lightConfig => { 177 switch (lightConfig.type) { 178 case 'ambient': 179 light = new AmbientLight(...lightConfig.params) 180 break 181 case 'directional': 182 light = new DirectionalLight(...lightConfig.params) 183 break 184 case 'point': 185 light = new PointLight(...lightConfig.params) 186 break 187 default: 188 console.error(`Unknown light type ${lightConfig.type}`) 189 } 190 if (light) { 191 if (typeof lightConfig.props === 'object') {
192 Object.keys(lightConfig.props).forEach(key => { 193 if (key === 'position') { 194 light.position.set(...lightConfig.props[key]) 195 } else light[key] = lightConfig.props[key] 196 }) 197 } 198 scene.add(light) 199 lights.push(light) 200 } 201 }) 202 } 203 return lights 204}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.