| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414 | // 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/menulet delta =0, millis = 0let timeIds=[]; // double clickvar timeStart,timeEnd,timeLongPress; // long presslet is_key_down = false,key_down_frequency = 0;let is_pc = falseconst LONG_PRESS_TIMES = 3let 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 +="<br>" +e.key + ' '+e.keyCode    if(key_down_frequency<LONG_PRESS_TIMES){        switch(e.keyCode){            case 38://ArrowUp                if(model==='full'){                    doubleDelay(walkingCamera,lookDirection,2)                }else if(model==='menu'){                }                break            case 40: //ArrowDown                if(model==='full'){                    doubleDelay(null,lookDirection,1)                }else if(model==='menu'){                    const firstChild = document.getElementById('menu').firstChild                    firstChild.className = 'panoSelect'                }                break            case 37: //ArrowLeft                if(model==='full'){                    doubleDelay(zoomIn,lookDirection,3)                }else if(model==='menu'){                    let pano_select = -1                    const nodess = document.getElementById("menu").childNodes;                    for(let i =0;i<nodess.length-1;i++){                        if(nodess[i].className==='panoSelect'){                            pano_select=i===0?nodess.length -2:i-1                            nodess[i].className = 'pano'                            nodess[pano_select].className = 'panoSelect'                            const fromLeft = document.getElementById('menu').scrollLeft                            const toLeft = 270*pano_select;                            const coords = {x: fromLeft, y: 0} // Start at (0, 0)                            const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'.                                .to({x: toLeft, y: 200}, 1000) // Move to (300, 200) in 1 second.                                .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.                                .onUpdate(() => {                                    // 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<nodess.length-1;i++){                        if(nodess[i].className==='panoSelect'){                            pano_select=nodess.length-2===i?0:i+1                            // document.getElementById('menu').scrollLeft =270*pano_select;                            const fromLeft = document.getElementById('menu').scrollLeft                            const toLeft = 270*pano_select;                            const coords = {x: fromLeft, y: 0} // Start at (0, 0)                            const tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'.                                .to({x: toLeft, y: 200}, 1000) // Move to (300, 200) in 1 second.                                .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.                                .onUpdate(() => {                                    // 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<nodess.length;i++){                        if(nodess[i].className==='panoSelect'){                            pano_select=nodess[i].getAttribute('data-id')                            i = nodess.length                        }                     }                    if(pano_select===-1){                        house.menu_control_select = 0                        const firstChild = document.getElementById('menu').firstChild                        firstChild.className = 'panoSelect'                        document.getElementById('menu').scrollLeft = 0                    }                    doubleDelay(defaultCameraFov,displayMenu,null)                }else if(model==='menu'){                    model = 'full'                    document.getElementById("menu").style.display='none';                    // document.getElementById("menuTip").style.display='none';                    // document.getElementById("menuTitle").style.display='none';                    let pano_select = -1                    const nodess = document.getElementById("menu").childNodes;                    for(let i =0;i<nodess.length;i++){                        if(nodess[i].className==='panoSelect'){                            pano_select=nodess[i].getAttribute('data-id')                            i = nodess.length                            house.idx = pano_select                        }                     }                    autoUpdateMaterial(house.idx)                }                  break            case 48: // auto play                isAutoPlay = !isAutoPlay                camera.fov = isAutoPlay?75:45                camera.updateProjectionMatrix();                var points=document.getElementById("redPoints");                while (points.firstChild) {                    points.removeChild(points.firstChild);                }                                    break            case 49:                // document.getElementById('menu').scrollLeft+=270;                        break            default:                break        }            }    key_down_frequency = 0}// function onKeyUp(e){//     switch(e.keyCode){//         case 38://ArrowUp//             if(model==='full'){//                // doubleDelay(walkingCamera,lookDirection,2)//             }else if(model==='menu'){                //             }            //             break//         case 40: //ArrowDown//             if(model==='full'){//                 //doubleDelay(null,lookDirection,1)//             }else if(model==='menu'){//                 // const firstChild = document.getElementById('menu').firstChild//                 // firstChild.className = 'panoSelect'//             }//             break//         case 37: //ArrowLeft//             if(model==='full'){//                 // doubleDelay(zoomIn,lookDirection,3)//             }else if(model==='menu'){//                 // let pano_select = -1    //                 // const nodess = document.getElementById("menu").childNodes;//                 // for(let i =0;i<nodess.length;i++){//                 //     if(nodess[i].className==='panoSelect'){//                 //         pano_select=i===0?nodess.length -1:i-1//                 //         nodess[i].className = 'pano'//                 //         nodess[pano_select].className = 'panoSelect'//                 //         document.getElementById('menu').scrollLeft =100*pano_select;//                 //         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<nodess.length;i++){//                 //     if(nodess[i].className==='panoSelect'){//                 //         pano_select=nodess.length-1===i?0:i+1//                 //         document.getElementById('menu').scrollLeft =100*pano_select;//                 //         nodess[i].className = 'pano'//                 //         nodess[pano_select].className = 'panoSelect'//                 //         i = nodess.length//                 //     } //                 // }//             }//             break//         case 13://Enter//             // single click//             if(model==='full'){//                 // doubleDelay(defaultCameraFov,displayMenu,null)//             }else if(model==='menu'){//                 // model = 'full'//                 // document.getElementById("menu").style.display='none';    //                 // let pano_select = -1//                 // const nodess = document.getElementById("menu").childNodes;//                 // for(let i =0;i<nodess.length;i++){//                 //     if(nodess[i].className==='panoSelect'){//                 //         // console.log(nodess[i].getAttribute('data-id'),'hkkkkkkkkkkkkk' )//                 //         // pano_select=i//                 //         pano_select=nodess[i].getAttribute('data-id')//                 //         i = nodess.length//                 //     } //                 // }//                 // house.idx  = pano_select//                 // autoUpdateMaterial(house.idx)//             }//             break//         case 48: // auto play//             break//         case 49: //`1`//             break//         default://             break//     }// }function onWindowResize() {    camera.aspect = window.innerWidth / window.innerHeight;    camera.updateProjectionMatrix();    renderer.setSize(window.innerWidth, window.innerHeight);}function pauseEvent(e){    if(e.stopPropagation) e.stopPropagation();    if(e.preventDefault) e.preventDefault();    e.cancelBubble=true;    e.returnValue=false;    return false;}function onPointerStart(event) {    isUserInteracting = true;    if(is_pc){        // pauseEvent(event)    }    // if(model==='menu'){    //         // }    var clientX = event.clientX || event.touches[0].clientX;    var clientY = event.clientY || event.touches[0].clientY;    onMouseDownMouseX = clientX;    onMouseDownMouseY = clientY;    onMouseDownLon = lon;    onMouseDownLat = lat;}function onPointerMove(event) {    if (isUserInteracting === true) {        var clientX = event.clientX || (typeof(event.touches)!=='undefined'?event.touches[0].clientX:0);        var clientY = event.clientY || (typeof(event.touches)!=='undefined'?event.touches[0].clientY:0);        // lon = (onMouseDownMouseX - clientX) * 0.1 + onMouseDownLon;        // lat = (clientY - onMouseDownMouseY) * 0.1 + onMouseDownLat;        if(model==='full'){            lon = (onMouseDownMouseX - clientX) * 0.075 + onMouseDownLon;            lat = (clientY - onMouseDownMouseY) * 0.075 + onMouseDownLat;        }else if(model==='menu'){            const deltaX = (onMouseDownMouseX - clientX) * 0.031             const fromLeft = document.getElementById('menu').scrollLeft            const toLeft = fromLeft + deltaX            document.getElementById('menu').scrollLeft = toLeft        }    }}function onPointerUp() {    isUserInteracting = false;}function onDocumentMouseWheel(event) {    var fov = camera.fov + event.deltaY * 0.05;    camera.fov = THREE.MathUtils.clamp(fov, 15, 75);    camera.updateProjectionMatrix();}function IsPC(){      var userAgentInfo = navigator.userAgent;    var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");      var flag = true;      for (var v = 0; v < Agents.length; v++) {          if (userAgentInfo.indexOf(Agents[v]) > 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<mesh.material.length;i++){        if(mesh.material[i].name===face){            mesh.material[i].map.dispose()            mesh.material[i].map = texture            mesh.material[i].map.needsUpdate = true;            i=mesh.material.length        }    }}function updateFaceCamera(texture,nextId,idx,face){        const coords = {x: camera.fov*35/20, y: lat,z:lon} // Start at (0, 0)    const fov = camera.fov    lat = nextId.angle.lat    lon = nextId.angle.lon    // for(let i=spotGroup.children.length-1;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/rightfunction 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)        document.getElementById('debug').innerHTML +="<br> onPress:" +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 +="<br>" +url                return;                // window.location.replace(url)                  // window.location.href = url                  // VrBrowserToJS.vrBrowerExit()            }       }       return;    }});window.onBackEvent= function(){    document.getElementById('debug').innerHTML +="<br>" +'window.onBackEvent'}
 |