Download src/three-console.js from Vintendopower/html-trap-2026: direct link, hf CLI and curl.
- Browser
- Download file 6.68 kB
-
https://huggingface.co/spaces/Vintendopower/html-trap-2026/resolve/main/src/three-console.js
- Command line
-
hf download hf://spaces/Vintendopower/html-trap-2026/src/three-console.js
-
curl -L -o three-console.js https://huggingface.co/spaces/Vintendopower/html-trap-2026/resolve/main/src/three-console.js
6.68 kB
| // Progressive WebGL presentation layer. The game remains usable if this optional | |
| // module or WebGL is unavailable. | |
| import * as THREE from 'three'; | |
| import {assetUrl} from './asset-resolver.js'; | |
| import {OBJLoader} from 'https://huggingface.co/datasets/Vintendopower/nighttrap-media/resolve/main/assets/vendor/OBJLoader.js'; | |
| const canvas=document.getElementById('threeConsole'); | |
| if(canvas){ | |
| const host=canvas.parentElement; | |
| const renderer=new THREE.WebGLRenderer({canvas,alpha:true,antialias:true,powerPreference:'low-power'}); | |
| renderer.setPixelRatio(Math.min(window.devicePixelRatio||1,1.5)); | |
| renderer.outputColorSpace=THREE.SRGBColorSpace; | |
| const scene=new THREE.Scene(); | |
| const camera=new THREE.PerspectiveCamera(34,1,.1,100); | |
| camera.position.set(0,1.8,8.4);camera.lookAt(0,.2,0); | |
| scene.add(new THREE.AmbientLight(0x6b8290,.38)); | |
| const redLight=new THREE.PointLight(0xff3024,1.3,12);redLight.position.set(-3,2,3);scene.add(redLight); | |
| const greenLight=new THREE.PointLight(0x7dffb0,1.1,10);greenLight.position.set(3,1,2);scene.add(greenLight); | |
| const consoleGroup=new THREE.Group();scene.add(consoleGroup); | |
| const frameMaterial=new THREE.MeshStandardMaterial({color:0x0a1115,metalness:.82,roughness:.3,transparent:true,opacity:.92}); | |
| const trimMaterial=new THREE.MeshStandardMaterial({color:0x334650,metalness:.7,roughness:.26,emissive:0x08151b,emissiveIntensity:.8}); | |
| const frame=new THREE.Mesh(new THREE.BoxGeometry(8.2,4.5,.42),frameMaterial);frame.position.set(0,.1,-.3);consoleGroup.add(frame); | |
| const trim=new THREE.Mesh(new THREE.BoxGeometry(7.8,4.1,.12),trimMaterial);trim.position.set(0,.1,-.05);consoleGroup.add(trim); | |
| const roomMaterials=[]; | |
| for(let i=0;i<8;i++){ | |
| const material=new THREE.MeshStandardMaterial({color:0x15252c,emissive:0x143e4a,emissiveIntensity:.25,metalness:.4,roughness:.36}); | |
| roomMaterials.push(material); | |
| const x=-3.25+(i%4)*2.17,y=-2.0+Math.floor(i/4)*.72; | |
| const slot=new THREE.Mesh(new THREE.BoxGeometry(1.72,.46,.08),material);slot.position.set(x,y,.08);consoleGroup.add(slot); | |
| } | |
| const sweep=new THREE.Mesh(new THREE.BoxGeometry(7.1,.018,.02),new THREE.MeshBasicMaterial({color:0x79ffc4,transparent:true,opacity:.55}));sweep.position.set(0,.2,.2);consoleGroup.add(sweep); | |
| const grid=new THREE.GridHelper(14,28,0x2f5360,0x172c35);grid.position.y=-2.35;grid.rotation.x=.03;grid.material.transparent=true;grid.material.opacity=.25;scene.add(grid); | |
| const textureLoader=new THREE.TextureLoader(); | |
| const mapTexture=textureLoader.load(assetUrl('assets/images/sharedassets1_369.png'),texture=>{texture.colorSpace=THREE.SRGBColorSpace;}); | |
| const mapPanel=new THREE.Mesh(new THREE.PlaneGeometry(1.55,.98),new THREE.MeshBasicMaterial({map:mapTexture,transparent:true,opacity:.72})); | |
| mapPanel.position.set(3.02,.52,.19);mapPanel.rotation.y=-.08;consoleGroup.add(mapPanel); | |
| const buttonTexture=textureLoader.load(assetUrl('assets/images/sharedassets1_425.png'),texture=>{texture.colorSpace=THREE.SRGBColorSpace;}); | |
| const buttonPanel=new THREE.Mesh(new THREE.PlaneGeometry(1.2,.64),new THREE.MeshBasicMaterial({map:buttonTexture,transparent:true,opacity:.42})); | |
| buttonPanel.position.set(-3.12,.55,.2);buttonPanel.rotation.y=.08;consoleGroup.add(buttonPanel); | |
| const noiseTexture=textureLoader.load(assetUrl('assets/images/sharedassets1_409.png'),texture=>{texture.colorSpace=THREE.SRGBColorSpace;texture.wrapS=texture.wrapT=THREE.RepeatWrapping;}); | |
| const noiseMaterial=new THREE.MeshBasicMaterial({map:noiseTexture,transparent:true,opacity:.10,depthWrite:false,blending:THREE.AdditiveBlending}); | |
| const noisePlane=new THREE.Mesh(new THREE.PlaneGeometry(7.6,4.0),noiseMaterial);noisePlane.position.set(0,.1,.24);consoleGroup.add(noisePlane); | |
| const extractedLayouts={}; | |
| const objLoader=new OBJLoader(); | |
| const layoutVariants={night:assetUrl('assets/models/sharedassets2_12_PlayUp_1994-layout.obj'),sotc:assetUrl('assets/models/sharedassets3_4_PlayUp_1993.obj'),survivor:assetUrl('assets/models/sharedassets4_5_PlayUp_1992.obj')}; | |
| function selectLayout(){const variant=eraOverride==='auto'?(currentMode.startsWith('sotc')?'sotc':currentMode.startsWith('survivor')?'survivor':'night'):({1992:'survivor',1993:'sotc',1994:'night'}[eraOverride]||'night');Object.entries(extractedLayouts).forEach(([key,object])=>{object.visible=key===variant;});} | |
| Object.entries(layoutVariants).forEach(([key,url])=>objLoader.load(url,object=>{ | |
| const bounds=new THREE.Box3().setFromObject(object),size=bounds.getSize(new THREE.Vector3()),center=bounds.getCenter(new THREE.Vector3()); | |
| object.position.sub(center);object.scale.setScalar(6.6/Math.max(size.x,size.y,size.z));object.position.set(0,.05,-.18); | |
| object.traverse(node=>{if(!node.isMesh)return;node.material=new THREE.MeshStandardMaterial({color:key==='sotc'?0x8b3438:key==='survivor'?0x6670a0:0x4f7486,emissive:key==='sotc'?0x260607:key==='survivor'?0x11182d:0x081a26,emissiveIntensity:.55,metalness:.7,roughness:.38,transparent:true,opacity:.72});node.material.depthWrite=false;}); | |
| extractedLayouts[key]=object;scene.add(object);selectLayout(); | |
| },undefined,()=>{})); | |
| let currentRoom=0,currentMode='night',eraOverride='auto',alert=false,last=performance.now(); | |
| function resize(){const w=host.clientWidth,h=host.clientHeight;if(!w||!h)return;renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();} | |
| function setMode(mode){currentMode=mode;const sotc=String(mode).startsWith('sotc');frameMaterial.color.setHex(sotc?0x170b0d:0x0a1115);trimMaterial.color.setHex(sotc?0x5e2426:0x334650);redLight.color.setHex(sotc?0xff5b39:0xff3024);selectLayout();} | |
| function setEra(value){eraOverride=['auto','1992','1993','1994'].includes(value)?value:'auto';selectLayout();} | |
| function setRoom(index){currentRoom=Math.max(0,Math.min(7,Number(index)||0));roomMaterials.forEach((m,i)=>{m.emissiveIntensity=i===currentRoom ? .95 : .16;m.color.setHex(i===currentRoom?0x284b50:0x15252c);});} | |
| function setAlert(value){alert=!!value;greenLight.intensity=alert?.35:1.1;redLight.intensity=alert?2.2:1.3;} | |
| function animate(now){const dt=Math.min(.05,(now-last)/1000);last=now;sweep.position.y=1.8-((now*.00023)%1)*3.6;sweep.material.opacity=.28+.18*Math.sin(now*.003);if(noiseTexture)noiseTexture.offset.x=(now*.00008)%1,noiseTexture.offset.y=(now*.00011)%1;noiseMaterial.opacity=alert?.18:.10;consoleGroup.rotation.y=Math.sin(now*.00035)*.012;redLight.intensity+=(alert?2.2:1.3-redLight.intensity)*dt*3;renderer.render(scene,camera);requestAnimationFrame(animate);} | |
| window.addEventListener('resize',resize);resize();setRoom(0);requestAnimationFrame(animate); | |
| window.nightTrapVisuals={setMode,setEra,setRoom,setAlert}; | |
| } | |