// import * as THREE from './js/three.module.js'; // // import {OrbitControls} from './js/OrbitControls.js'; // import TWEEN from './js/tween.esm.js'; // const TWEEN = require('@tweenjs/tween.esm.js') let camera, scene, renderer,controls,material,mesh; let isAutoPlay = false,model = 'full' // full/menu let delta =0, millis = 0 let timeIds=[]; // double click var timeStart,timeEnd,timeLongPress; // long press let is_key_down = false,key_down_frequency = 0; let is_pc = false const LONG_PRESS_TIMES = 3 let loader=null; let materialArray=null; var container; const house ={ // curr_id:2, idx:0, // direction:'B', nextId:null, isLoading:false, numLoaded:0, texture:{ id:-1, curr:null, next:null, isloading:false, }, config:{ lat_step:10, lon_step:10, }, title:"南京世茂项目", src:[ {id:1,name:"01frontGate",title:'01正门',home:{T:50,R:70},view:{lat:-0.825, lon:19.875},image:"panos/01frontGate.png", L:{id:14,angle:{lat: -10, lon: 16.3},offset:180},R:{id:25,angle:{lat: -13.7, lon: 75.3},offset:-70},F:null,B:null,LF:null, LB:null,RF:null,RB:null, spots:[{id:14,name:'14',position:{x: 230, y: -60, z: 50},rotate:{x:Math.PI/2,y:0,z:0},scale:{x:1,y:1,z:1},angle:{lat: -10, lon: 16.3},offset:180}, {id:25,name:'25',position:{x: -90, y: -60, z: -30},rotate:{x:Math.PI/2,y:0,z:0},scale:{x:1,y:1,z:1},angle:{lat: -13.7, lon: 75.3},offset:-70}]}, {id:2,name:"02masterBedroom",title:'02主卧',home:{T:83,R:45},view:{lat: -7.8000000000000025 ,lon: 180},image:"panos/02masterBedroom.png", L:null,R:{id:4,angle:{lat: -9.5, lon: 50},offset:180},F:{id:6,angle:{lat: -4, lon: -77},offset:-90},B:{id:3,angle:{lat: -3.7, lon: 0.5}, offset:0},LF:null,LB:null,RF:null,RB:null, }, {id:3,name:"03masterBedroom",title:'03主卧',home:{T:85,R:36},view:{lat: -2.5500000000000007 ,lon: 110.1}, image:"panos/03masterBedroom.png",L:null,R:{id:4,angle:{lat: -13.6, lon: 54},offset:180},F:{id:2,angle:{lat: 2.7, lon: 16.7}, offset:90},B:null,LF:null,LB:null,RF:null,RB:null, }, {id:4,name:"04masterBedroom",title:'04主卧',home:{T:75,R:30},view:{lat: -4.425 ,lon: 219.52499999999998}, image:"panos/04masterBedroom.png",L:null,R:{id:3,angle:{lat: 0, lon: 13.5},offset:0},F:null,B:{id:2,angle:{lat: 3, lon: 17.1},offset:90}, LF:null,LB:null,RF:null,RB:null, }, {id:5,name:"05masterBedroomToilet",title:'05主卧卫生间',home:{T:60,R:30},view:{lat: -4.725 ,lon: 97.125}, image:"panos/05masterBedroomToilet.png",L:null,R:null,F:{id:7,angle:{lat: -13, lon: 50},offset:0},B:null,LF:null,LB:null, RF:null,RB:null, }, {id:6,name:"06masterBedroomPorch",title:'06主卧门廊',home:{T:66,R:45},view:{lat: -10.124999999999998 ,lon: 93.225}, image:"panos/06masterBedroomPorch.png",L:null,R:{id:25,angle:{lat: -10, lon: 150},offset:-75},F:{id:2,angle:{lat: -6.5, lon: -86}, offset:90},B:{id:7,angle:{lat: -2, lon: 146},offset:35},LF:null,LB:null,RF:null,RB:null, }, {id:7,name:"07masterBedroomCloakroom",title:'07主卧衣帽间',home:{T:60,R:48},view:{lat: -9.750000000000002 ,lon: 326.62499999999994}, image:"panos/07masterBedroomCloakroom.png",L:{id:6,angle:{lat: 1.9, lon: 86},offset:-90},R:null,F:null,B:null,LF:null,LB:{id:6, angle:{lat: 1.9, lon: 86},offset:-90},RF:null,RB:{id:5,angle:{lat: -3.2, lon: -80},offset:0}, }, {id:8,name:"08AguestRoom",title:'08客房',home:{T:90,R:100},view:{lat: -6.0749999999999975 ,lon: 191.55},image:"panos/08AguestRoom.png", L:null,R:{id:9,angle:{lat: -4.5, lon: -48},offset:-90},F:null,B:null,LF:null,LB:null,RF:null,RB:null, }, {id:9,name:"09guestRoomA",title:'09客房A',home:{T:80,R:90},view:{lat: -10.575000000000001 ,lon: 292.425},image:"panos/09guestRoomA.png", L:null,R:null,F:{id:8,angle:{lat: -5.7, lon: -25},offset:30},B:{id:10,angle:{lat: -6.4, lon: 187},offset:-90},LF:null,LB:null,RF:null, RB:null, }, {id:10,name:"10guestRoomAToilet",title:'10客房卫生间',home:{T:70,R:100},view:{lat: -4.874999999999999 ,lon: 83.85}, image:"panos/10guestRoomAToilet.png",L:null,R:null,F:{id:25,angle:{lat: 3.8, lon: -15},offset:-90},B:null,LF:null,LB:null, RF:null,RB:null, }, {id:11,name:"11guestRoomB",title:'11客房B',home:{T:85,R:70},view:{lat: -5.8500000000000005 ,lon: 102.74999999999999}, image:"panos/11guestRoomB.png",L:null,R:{id:12,angle:{lat: -2.8, lon: 17},offset:180},F:{id:25,angle:{lat: -7, lon: -118},offset:-60}, B:null,LF:null,LB:{id:13,angle:{lat: -1.4, lon: -172},offset:160},RF:null,RB:null, }, {id:12,name:"12guestRoomB",title:'12客房B',home:{T:80,R:60},view:{lat: -0.675000000000002 ,lon: 226.5},image:"panos/12guestRoomB.png", L:null,R:{id:11,angle:{lat: -10, lon: -43},offset:90},F:null,B:null,LF:null,LB:null,RF:null,RB:null, }, {id:13,name:"13guestRoomB",title:'13客房B',home:{T:95,R:70},view:{lat: -6.149999999999997 ,lon: 10.500000000000016}, image:"panos/13guestRoomB.png",L:{id:11,angle:{lat: -6, lon: 120},offset:60},R:null,F:null,B:null,LF:null,LB:null,RF:null,RB:null, }, {id:14,name:"14livingRoom",title:'14客厅',home:{T:20,R:70},view:{lat: -4.2 ,lon: 38.475},image:"panos/14livingRoom.png",L:null,R:null, F:{id:16,angle:{lat: 1.4, lon: 80},offset:180},B:null,LF:{id:17,angle:{lat: -2.4, lon: 36},offset:150},LB:null,RF:{id:15, angle:{lat: -6, lon: 148},offset:130},RB:{id:1,angle:{lat: -2.1, lon: 187},offset:180}, }, {id:15,name:"15livingRoom",title:'15客厅',home:{T:30,R:50},view:{lat: -7.574999999999999 ,lon: 50.025},image:"panos/15livingRoom.png", L:null,R:null,F:null,B:null,LF:{id:16,angle:{lat: -7.2, lon: -13},offset:180},LB:{id:14,angle:{lat: 0, lon: -57},offset:150}, RF:{id:22,angle:{lat: -1.4, lon: 73},offset:180},RB:{id:20,angle:{lat: 0, lon: 0},offset:0}, }, {id:16,name:"16livingRoom",title:'16客厅',home:{T:20,R:50},view:{lat: -7.199999999999999 ,lon: 170.92499999999998}, image:"panos/16livingRoom.png",L:{id:19,angle:{lat: -2, lon: -3},offset:180},R:{id:15,angle:{lat: -3, lon: 230},offset:120}, F:{id:22,angle:{lat: 4.5, lon: 119},offset:180},B:{id:14,angle:{lat: 2.5, lon: -80},offset:160},LF:{id:18,angle:{lat: -10, lon: -20}, offset:-130},LB:{id:17,angle:{lat: 0, lon: 0},offset:160},RF:null,RB:null, }, {id:17,name:"17livingRoom",title:'17客厅',home:{T:8,R:60},view:{lat: -7.125 ,lon: -1.5},image:"panos/17livingRoom.png", L:{id:23,angle:{lat: -1, lon: -236},offset:30},R:{id:16,angle:{lat: -8.2, lon: 178},offset:180},F:null,B:null,LF:{id:23, angle:{lat: -1.4, lon: -210},offset:80},LB:null,RF:{id:19,angle:{lat: -2, lon: 75},offset:180},RB:{id:14, angle:{lat: -6.3, lon: 221},offset:150}, }, {id:18,name:"18livingRoom",title:'18客厅',home:{T:8,R:40},view:{lat: -12.374999999999998 ,lon: 145.12499999999997}, image:"panos/18livingRoom.png",L:null,R:null,F:null,B:null,LF:null,LB:{id:24,angle:{lat: -3, lon: -52},offset:-120}, RF:{id:16,angle:{lat: 5.2, lon: 179},offset:180},RB:{id:19,angle:{lat: -1.2, lon: -81},offset:180}, }, {id:19,name:"19livingRoom",title:'19客厅',home:{T:8,R:50},view:{lat: -7.574999999999999 ,lon: 83.24999999999999}, image:"panos/19livingRoom.png",L:null,R:{id:16,angle:{lat: -8.2, lon: 178},offset:180},F:{id:18,angle:{lat: -2, lon: 75},offset:180}, B:{id:17,angle:{lat: -1.2, lon: -81},offset:180},LF:null,LB:{id:23,angle:{lat: -1, lon: -236},offset:0},RF:null, RB:{id:14,angle:{lat: -7, lon: 251},offset:120}, }, {id:20,name:"20livingRoom",title:'20客厅',home:{T:40,R:45},view:{lat: -4.35 ,lon: 16.34999999999999}, image:"panos/20livingRoom.png",L:{id:21,angle:{lat: -0.6, lon: -117},offset:150},R:{id:15,angle:{lat: 2, lon: 55},offset:120}, F:null,B:{id:22,angle:{lat: -1, lon: 70},offset:180},LF:null,LB:null,RF:{id:14,angle:{lat: -1.8, lon: -44},offset:180},RB:null, }, {id:21,name:"21livingRoom",title:'21客厅',home:{T:42,R:55},view:{lat: -3.0749999999999993 ,lon: 64.350000}, image:"panos/21livingRoom.png",L:null,R:null,F:{id:20,angle:{lat: 0, lon: -179},offset:0},B:null,LF:{id:20,angle:{lat: -1.1, lon: -190}, offset:0},LB:null,RF:null,RB:null, }, {id:22,name:"22livingRoom",title:'22客厅',home:{T:23,R:20},view:{lat: -8.475000000000001 ,lon: -135.674}, image:"panos/22livingRoom.png",L:null,R:null,F:null,B:null,LF:null,LB:null,RF:null,RB:{id:20,angle:{lat: -2, lon: 84},offset:0}, }, {id:23,name:"23kitchen",title:'23厨房',home:{T:-5,R:65},view:{lat: -11.174999999999999 ,lon: 278},image:"panos/23kitchen.png", L:null,R:null,F:null,B:{id:17,angle:{lat: 0, lon: 165},offset:180},LF:null,LB:{id:17,angle:{lat: -5.7, lon: 197},offset:160}, RF:null,RB:null, }, {id:24,name:"24laundry",title:'24洗衣间',home:{T:-5,R:40},view:{lat: -2.099999999999999 ,lon: 139.79999},image:"panos/24laundry.png", L:null,R:null,F:null,B:null,LF:null,LB:null,RF:{id:18,angle:{lat: 1.3, lon: 152},offset:230},RB:null, }, {id:25,name:"25frontGatePorch",title:'25前门门廊',home:{T:65,R:75},view:{lat: -6.675000000000004 ,lon: 248.7749999}, image:"panos/25frontGatePorch.jpg",L:{id:6,angle:{lat: -6, lon: 47},offset:-90},R:{id:10,angle:{lat: 2.2, lon: -85},offset:180}, F:{id:11,angle:{lat: -5, lon: -67},offset:60},B:{id:1,angle:{lat: 1.7, lon: 17},offset:180},LF:null,LB:null, RF:{id:9,angle:{lat: -10, lon: -230},offset:-90},RB:{id:1,angle:{lat: 0, lon: 0},offset:180}, }, ], direction:[ {id:1,name:"B",at:{x:0,y:0,z:-1}}, {id:2,name:"F",at:{x:0,y:0,z:1}}, {id:3,name:"R",at:{x:-1,y:0,z:0}}, {id:4,name:"L",at:{x:1,y:0,z:0}}, {id:5,name:"down",at:{x:0,y:1,z:0}}, {id:6,name:"up",at:{x:0,y:-1,z:0}}, {id:1,name:"LF",at:{x:1,y:0,z:1}}, {id:2,name:"RF",at:{x:-1,y:0,z:1}}, {id:3,name:"LB",at:{x:1,y:0,z:-1}}, {id:4,name:"RB",at:{x:-1,y:0,z:-1}}, ], playList:{ idx:0, orders:[ {id:1},{id:14},{id:17},{id:23},{id:19},{id:24},{id:18},{id:16},{id:22},{id:20},{id:21},{id:15}, {id:25},{id:2},{id:3},{id:4},{id:5},{id:6},{id:7},{id:8},{id:9},{id:10},{id:11},{id:12}, {id:13} ] }, menuList:[ {id:1},{id:2},{id:5},{id:9},{id:12},{id:16},{id:20},{id:17},{id:14} ] } var isUserInteracting = false, onMouseDownMouseX = 0, onMouseDownMouseY = 0, lon = 0, onMouseDownLon = 0, lat = 0, onMouseDownLat = 0, phi = 0, theta = 0; const spotGroup = new THREE.Group() init(); animate(); function init() { container = document.getElementById('container'); // camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100); camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5100); camera.target = new THREE.Vector3(0, 0, 0); scene = new THREE.Scene(); // invert the geometry on the x-axis so that all of the faces point inward const geometry = new THREE.BoxGeometry(512, 512, 512); geometry.scale(-1, 1, 1); // if (!texture){ // loader = new THREE.TextureLoader(); loader = new THREE.TextureLoader().setPath('./panos/'); const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const panoId = urlParams.get('id')?urlParams.get('id'):0 const backurl = urlParams.get('backurl')?urlParams.get('backurl'):'pano3.html' house.idx = panoId house.backurl = backurl // var texture = new THREE.TextureLoader().load('images/02.png'); const imgPath = house.src[house.idx].image // const texture = new THREE.TextureLoader().load(imgPath); const fileName = house.src[house.idx].name // const texture = loader.load( // // urls of images used in the cube texture // [ // fileName+ '_b.png', // fileName+ '_f.png', // fileName+ '_u.png', // fileName+ '_d.png', //d // fileName+ '_l.png', // fileName+ '_r.png', // ]) // // let loader2 = new THREE.TextureLoader().setPath('./panos/'); materialArray = [ new THREE.MeshBasicMaterial( { name:'f',map: loader.load(fileName+ '4k_f.jpg') } ), new THREE.MeshBasicMaterial( { name:'b',map: loader.load(fileName+ '4k_b.jpg') } ), new THREE.MeshBasicMaterial( { name:'u',map: loader.load(fileName+ '4k_u.jpg') } ), new THREE.MeshBasicMaterial( { name:'d',map: loader.load(fileName+ '4k_d.jpg') } ), new THREE.MeshBasicMaterial( { name:'l',map: loader.load(fileName+ '4k_l.jpg') } ), new THREE.MeshBasicMaterial( { name:'r',map: loader.load(fileName+ '4k_r.jpg') } ), ]; setHomePosition() // } // // material = new THREE.MeshBasicMaterial({ envMap: texture}); mesh = new THREE.Mesh(geometry, materialArray); scene.add(mesh); var light = new THREE.AmbientLight( 0x404040 ); // soft white light scene.add( light ); renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); // camera.position.set( 1000, 2000, 10 ); window.camera=camera scene.add(spotGroup) initMenu() lat = house.src[house.idx].view.lat lon = house.src[house.idx].view.lon is_pc = IsPC() // controls = new OrbitControls( camera, renderer.domElement ); // controls.update(); // document.getElementById("map_img").addEventListener('mousedown', onPointerStart, false); document.addEventListener('mousedown', onPointerStart, false); document.addEventListener('mousemove', onPointerMove, false); document.addEventListener('mouseup', onPointerUp, false); document.addEventListener('wheel', onDocumentMouseWheel, false); document.addEventListener('touchstart', onPointerStart, false); document.addEventListener('touchmove', onPointerMove, false); document.addEventListener('touchend', onPointerUp, false); document.addEventListener('dblclick', onDbClickChange, false); // // document.addEventListener('dragover', function(event) { // event.preventDefault(); // event.dataTransfer.dropEffect = 'copy'; // }, false); // document.addEventListener('dragenter', function() { // document.body.style.opacity = 0.5; // }, false); // document.addEventListener('dragleave', function() { // document.body.style.opacity = 1; // }, false); // document.addEventListener('drop', function(event) { // event.preventDefault(); // var reader = new FileReader(); // reader.addEventListener('load', function(event) { // material.map.image.src = event.target.result; // material.map.needsUpdate = true; // }, false); // reader.readAsDataURL(event.dataTransfer.files[0]); // document.body.style.opacity = 1; // }, false); document.addEventListener('keydown', onKeyDown); document.addEventListener('keyup', onKeyUp); window.addEventListener('resize', onWindowResize, false); } function initMenu(){ var menu=document.getElementById("menu"); while (menu.firstChild) { menu.removeChild(menu.firstChild); } let mid = 0 for(let item of house.menuList){ const dpano = document.createElement("div"); dpano.className = 'pano' // dpano.attr({'data-id':item.id}) for(let i in house.src){ if(house.src[i].id===item.id){ mid = i break } } dpano.setAttribute('data-id',mid); const title = document.createElement("div"); title.className = 'title' title.innerHTML = house.src[mid].title const thumb = document.createElement("div"); thumb.className = 'thumb' // thumb.innerHTML = house.src[i].name const img=document.createElement("img"); img.src= './panos/'+house.src[mid].name + '4k_b.jpg'; thumb.appendChild(img); dpano.appendChild(title); dpano.appendChild(thumb); menu.appendChild(dpano); } const ddiv = document.createElement("div"); ddiv.innerHTML='-' ddiv.className = 'panoEnd' menu.appendChild(ddiv); // var menuTitle=document.getElementById("menuTitle"); // menuTitle.innerHTML = house.title } function walkingCamera(){ const d = getCameraDirection() walkOn(d) } function zoomIn(){ fov = camera.fov + 10 fov = THREE.MathUtils.clamp(fov, 15, 75); if(fov!==camera.fov){ updateCameraTo(fov) } } function zoomOut(){ fov = camera.fov - 10 fov = THREE.MathUtils.clamp(fov, 15, 75); if(fov!==camera.fov){ updateCameraTo(fov) } } function displayMenu(){ model = 'menu' document.getElementById("menu").style.display='flex'; // document.getElementById("menuTitle").style.display='flex'; // document.getElementById("menuTip").style.display='flex'; // // setTimeout( function(){ // document.getElementById("menuTip").style.display='none'; // }, 5000 ); } function doubleDelay(doubleCallback,callback,p){ timeId = setTimeout( function(){ if(Date.now()-delta<400){ for(let i in timeIds){ clearTimeout(timeIds[i]) } // const d = getCameraDirection() // walkOn(d) if(doubleCallback){ doubleCallback() } }else{ // lookDirection(2) callback(p) } }, 400 ); timeIds.push(timeId) } function onKeyDown(e){ key_down_frequency++ delta = Date.now() if(key_down_frequency>LONG_PRESS_TIMES){ switch(e.keyCode){ case 38://ArrowUp lat +=1.5 break case 40: //ArrowDown lat -=1.5 break case 37: //ArrowLeft lon -= 1.5 break case 39://ArrowRight lon += 1.5 break case 13://Enter isAutoPlay = true break default: break } } } function onKeyUp(e){ // console.log(e.keyCode) document.getElementById('debug').innerHTML +="
" +e.key + ' '+e.keyCode if(key_down_frequency { // Called after tween.js updates 'coords'. // Move 'box' to the position described by 'coords' with a CSS translation. document.getElementById('menu').scrollLeft = coords.x }) .start() // Start the tween immediately. i = nodess.length } } } break case 39://ArrowRight if(model==='full'){ doubleDelay(zoomOut,lookDirection,4) }else if(model==='menu'){ let pano_select = -1 const nodess = document.getElementById("menu").childNodes; for(let i =0;i { // Called after tween.js updates 'coords'. // Move 'box' to the position described by 'coords' with a CSS translation. document.getElementById('menu').scrollLeft = coords.x }) .start() // Start the tween immediately. nodess[i].className = 'pano' nodess[pano_select].className = 'panoSelect' i = nodess.length } } } break case 13://Enter if(model==='full'){ let pano_select = -1 const nodess = document.getElementById("menu").childNodes; for(let i =0;i 0) { flag = false; break; } } return flag; } //------------------------------------------ function onDbClickChange(event){ const d = getCameraDirection() walkOn(d) } function getCameraDirection(){ // camera.rotation.y =Math.PI/2 let min_angle = Math.PI let target_name = "" const cameraTarget = camera.target.normalize() for(const d in house.direction){ const dat = new THREE.Vector3(house.direction[d].at.x,house.direction[d].at.y,house.direction[d].at.z).normalize() const angle = cameraTarget.angleTo(dat) if(min_angle>angle){ min_angle = angle target_name = house.direction[d].name } } return target_name } function walkOn(d){ let nextId = null switch(d){ case 'L': nextId = house.src[house.idx].L break case 'R': nextId = house.src[house.idx].R break case 'F': nextId = house.src[house.idx].F break case 'B': nextId = house.src[house.idx].B break case 'LF': nextId = house.src[house.idx].LF break case 'LB': nextId = house.src[house.idx].LB break case 'RF': nextId = house.src[house.idx].RF break case 'RB': nextId = house.src[house.idx].RB break default: break } if(nextId&&!house.isLoading){ changeTexture(nextId) }else{ moveNull() } } function changeTexture(nextId){ const idx = getIdxFromId(nextId.id) house.numLoaded = 0 house.isLoading = true // document.getElementById('tip').style.display = 'flex' updateFaceTexture(nextId,idx,'f') updateFaceTexture(nextId,idx,'b') updateFaceTexture(nextId,idx,'l') updateFaceTexture(nextId,idx,'r') updateFaceTexture(nextId,idx,'u') updateFaceTexture(nextId,idx,'d') } function updateFaceTexture(nextId,idx, face){ const imgPath = house.src[idx].name +"4k_"+face+'.jpg' // load a resource loader.load( // resource URL imgPath, // onLoad callback function ( texture ) { house.numLoaded++ updateFaceMaterial(texture,face) if(house.numLoaded===mesh.material.length){ updateFaceCamera(texture,nextId,idx,face) } }, // onProgress callback currently not supported undefined, // onError callback function ( err ) { console.error( 'An error happened.' ); } ); } function updateFaceMaterial(texture,face){ for(let i=0;i=0;i--){ // spotGroup.remove(spotGroup.children[i]) // } const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. .to({x:fov,y:nextId.angle.lat,z:nextId.angle.lon}, 1200) // Move to (300, 200) in 1 second. .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. .onUpdate((e,t) => { camera.fov = coords.x camera.updateProjectionMatrix(); }) .onComplete(()=>{ house.nextId = nextId house.idx = idx camera.fov = fov camera.updateProjectionMatrix(); house.isLoading = false // document.getElementById('tip').style.display = 'none' setHomePosition() }) .start() // Start the tween immediately. } function range360(a){ while(a>180){ a -=360 } while(a<-180){ a +=360 } return a } function defaultCameraFov(){ let ilat = range360(lat) let ilon = range360(lon) const coords = {x: camera.fov, y: ilat,z:ilon} // Start at (0, 0) const fov = 45 const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. .to({x:fov,y:0,z:0}, 1200) // Move to (300, 200) in 1 second. .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. .onUpdate((e,t) => { camera.fov = coords.x camera.updateProjectionMatrix(); // lat = coords.y lon = coords.z }) .onComplete(()=>{ // house.nextId = nextId // house.idx = idx // camera.fov = fov // camera.updateProjectionMatrix(); // house.isLoading = false // document.getElementById('tip').style.display = 'none' }) .start() // Start the tween immediately. } // ------------- auto update material ------------ function autoLoadNextTexture(idx,face){ const imgPath = house.src[idx].name +"_"+face+'.jpg' // for(let i=spotGroup.children.length-1;i>=0;i--){ // spotGroup.remove(spotGroup.children[i]) // } // load a resource loader.load( // resource URL imgPath, // onLoad callback function ( texture ) { house.numLoaded++ updateFaceMaterial(texture,face) if(house.numLoaded===mesh.material.length){ house.isLoading = false // document.getElementById('tip').style.display = 'none' lat = house.src[idx].view.lat lon = house.src[idx].view.lon setHomePosition() } }, // onProgress callback currently not supported undefined, // onError callback function ( err ) { console.error( 'An error happened.' ); } ); } function autoUpdateMaterial(idx){ house.numLoaded = 0 house.isLoading = true // document.getElementById('tip').style.display = 'flex' autoLoadNextTexture(idx,'f') autoLoadNextTexture(idx,'b') autoLoadNextTexture(idx,'l') autoLoadNextTexture(idx,'r') autoLoadNextTexture(idx,'u') autoLoadNextTexture(idx,'d') } function updateCameraTo(fov){ const coords = {x: camera.fov, y: 0} // Start at (0, 0) const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. .to({x:fov,y:0}, 600) // Move to (300, 200) in 1 second. .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. .delay(300) .onUpdate((e,t) => { camera.fov = coords.x camera.updateProjectionMatrix(); }) .onComplete(()=>{ }) .start() // Start the tween immediately. } function setHomePosition(){ // const angle = house.src[house.idx].home.A const top = house.src[house.idx].home.T const right = house.src[house.idx].home.R document.getElementById('cam').style.top = top + 'px'; document.getElementById('cam').style.right = right+ 'px'; if(!isAutoPlay){ updateMapPoint() } } function updateHome(){ if(!house.isLoading){ const offset = house.nextId!==null?house.nextId.offset:180 const angle = lon + offset document.getElementById('cam').style.transform = 'rotate('+angle+'deg)'; } } function moveNull(){ const coords = {x: camera.fov, y: 0} // Start at (0, 0) const fov = camera.fov-5 const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. .to({x:fov,y:0}, 400) // Move to (300, 200) in 1 second. .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. .onUpdate((e,t) => { camera.fov = coords.x camera.updateProjectionMatrix(); }) .onComplete(()=>{ moveNullBack() }) .start() // Start the tween immediately. } function moveNullBack(){ lookZoom(5,400) } function lookZoom(z=5,t=600){ const fromX = camera.fov const coords = {x: fromX, y: 0} // Start at (0, 0) const toX = camera.fov + z const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. .to({x:toX,y:0}, t) // Move to (300, 200) in 1 second. .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. .onUpdate((e,t) => { camera.fov = coords.x camera.updateProjectionMatrix(); }) .start() // Start the tween immediately. } // direction 1/up 2/down 3/left 4/right function lookDirection(d=1){ const fromX = d===1||d===2?lat:lon const coords = {x: fromX, y: 0} // Start at (0, 0) const toX = d===1?lat-house.config.lat_step:d===2?lat+house.config.lat_step:d===3?lon-house.config.lon_step:lon+house.config.lon_step const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. .to({x:toX,y:0}, 600) // Move to (300, 200) in 1 second. .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. .onUpdate((e,t) => { if(d===1||d===2){ lat = coords.x }else{ lon = coords.x } }) .start() // Start the tween immediately. } function updateMapPoint(){ const idx = house.idx let id = -1 var points=document.getElementById("redPoints"); while (points.firstChild) { points.removeChild(points.firstChild); } // points.remove(); if(house.src[idx].L){ id = house.src[idx].L.id - 1 createMapPoint(id) } if(house.src[idx].R){ id = house.src[idx].R.id - 1 createMapPoint(id) } if(house.src[idx].F){ id = house.src[idx].F.id - 1 createMapPoint(id) } if(house.src[idx].B){ id = house.src[idx].B.id - 1 createMapPoint(id) } if(house.src[idx].LF){ id = house.src[idx].LF.id - 1 createMapPoint(id) } if(house.src[idx].LB){ id = house.src[idx].LB.id - 1 createMapPoint(id) } if(house.src[idx].RF){ id = house.src[idx].RF.id - 1 createMapPoint(id) } if(house.src[idx].RB){ id = house.src[idx].RB.id - 1 createMapPoint(id) } } function createMapPoint(id){ const top = house.src[id].home.T const right = house.src[id].home.R const img=document.createElement("img"); img.src="panos/redPoint.png"; img.style.position = 'absolute' img.style.top = top +15+ 'px'; img.style.right = right-5+ 'px'; img.style.width = 8+ 'px'; img.style.height = 8+ 'px'; const points=document.getElementById("redPoints"); points.appendChild(img); } function getIdxFromId(id){ let idx = -1 for(const item in house.src){ if(house.src[item].id===id){ idx = item break } } return idx } function animate() { requestAnimationFrame(animate); update(); } function update() { // controls.update(); if (isUserInteracting === false) { // lon += 0.1; } if(isAutoPlay){ // if(lon>360&&!house.texture.isloading){ if(lon>360&&!house.isloading){ lon = 0 // house.idx++ // if(house.idx>=house.src.length){ // house.idx = 0 // } house.playList.idx++ if(house.playList.idx>=house.playList.orders.length){ house.playList.idx = 0 } for(let i in house.src){ if(house.src[i].id===house.playList.orders[house.playList.idx].id){ house.idx = i break } } // house.idx = house.playList.orders[house.playList.idx].id-1 autoUpdateMaterial(house.idx) }else{ lon += 0.2; } } lat = Math.max(-85, Math.min(85, lat)); phi = THREE.MathUtils.degToRad(90 - lat); theta = THREE.MathUtils.degToRad(lon); camera.target.x = 512 * Math.sin(phi) * Math.cos(theta); camera.target.y = 512 * Math.cos(phi); camera.target.z = 512 * Math.sin(phi) * Math.sin(theta); updateHome() camera.lookAt(camera.target); TWEEN.update() renderer.render(scene, camera); } var btn = new tvSysBtnBind({ id: "Jdoc", className: "ctrlBtn", currentClass: "current", keyRemoveDefault: false, effect: "base", currentIndex: 0, onLoad: function(e) { // console.log(e); }, onPress:function() { var keyCode = this.event.keyCode; // alert('keyCode:'+keyCode) switch (keyCode) { case 37: // left // reloadData(); break; case 39: // right break; case 38: //up break; case 40: //down break; // case 13: //enter // break; case 33: //chanel + break; case 34: //chanel - break; case 48: //0 break; default: break; } }, onEnterPress: function() { }, onBack: function() { if(isAutoPlay){ isAutoPlay = false }else{ if(model==='menu'){ model = 'full' document.getElementById("menu").style.display='none'; // document.getElementById("menuTip").style.display='none'; // document.getElementById("menuTitle").style.display='none'; }else{ // window.location.href="index2.html?id="+house.idx const backurl = house.backurl const url = "pano3.html?id="+house.idx+'&backurl='+backurl console.log('url',url) document.getElementById('debug').innerHTML +="
" +url return; // window.location.replace(url) // window.location.href = url // VrBrowserToJS.vrBrowerExit() } } return; } }); window.onBackEvent= function(){ document.getElementById('debug').innerHTML +="
" +'window.onBackEvent' }