// 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)
document.getElementById('debug').innerHTML +="
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 +="
" +url
return;
// window.location.replace(url)
// window.location.href = url
// VrBrowserToJS.vrBrowerExit()
}
}
return;
}
});
window.onBackEvent= function(){
document.getElementById('debug').innerHTML +="
" +'window.onBackEvent'
}