manage.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. //管理js文件 获取modeldata.js 判断是否有特殊的字段,如果有就先加载SpecialScene.js 里面有对特殊场景处理的代码 否则就直接加载main
  2. var Manage = function(){
  3. this.weixinURL = "https://res.wx.qq.com/open/js/jweixin-1.2.0.js",
  4. this.time = "?"+new Date().getTime();
  5. this.loadAudio();
  6. //this.musicShouldPlay = true //一开始默认打开
  7. this.switchMusicState(true)//一开始默认打开
  8. }
  9. let allBgm = document.createElement('video')
  10. allBgm.src = './music/bgm.mp3'
  11. allBgm.autoplay = true
  12. allBgm.loop = true
  13. allBgm.volume = 0.1
  14. allBgm.load()
  15. //动态加载js文件
  16. Manage.prototype.LoadJs = function(_files, succes){
  17. /* 已加载文件缓存列表,用于判断文件是否已加载过,若已加载则不再次加载*/
  18. var classcodes = [];
  19. var FileArray = [];
  20. if (typeof _files === "object") {
  21. FileArray = _files;
  22. } else {
  23. /*如果文件列表是字符串,则用,切分成数组*/
  24. if (typeof _files === "string") {
  25. FileArray = _files.split(",");
  26. }
  27. }
  28. if (FileArray != null && FileArray.length > 0) {
  29. var LoadedCount = 0;
  30. for (var i = 0; i < FileArray.length; i++) {
  31. loadFile(FileArray[i], function() {
  32. LoadedCount++;
  33. if (LoadedCount == FileArray.length) {
  34. try {
  35. succes();
  36. }
  37. catch(err) {
  38. console.log("err: 您未定义回调");
  39. }
  40. }
  41. })
  42. }
  43. }
  44. /*加载JS文件,url:文件路径,success:加载成功回调函数*/
  45. function loadFile(url, success) {
  46. if (!FileIsExt(classcodes, url)) {
  47. var _ThisType = GetFileType(url);
  48. var ThisType = _ThisType.indexOf("?") == -1 ? _ThisType : _ThisType.substring(0,_ThisType.indexOf("?"));
  49. var fileObj = null;
  50. if (ThisType == ".js") {
  51. fileObj = document.createElement('script');
  52. fileObj.src = url;
  53. } else if (ThisType == ".css") {
  54. fileObj = document.createElement('link');
  55. fileObj.href = url;
  56. fileObj.type = "text/css";
  57. fileObj.rel = "stylesheet";
  58. } else if (ThisType == ".less") {
  59. fileObj = document.createElement('link');
  60. fileObj.href = url;
  61. fileObj.type = "text/css";
  62. fileObj.rel = "stylesheet/less";
  63. }
  64. success = success || function() {};
  65. fileObj.onload = fileObj.onreadystatechange = function() {
  66. if (!this.readyState || 'loaded' === this.readyState || 'complete' === this.readyState) {
  67. success();
  68. classcodes.push(url)
  69. }
  70. }
  71. document.getElementsByTagName('head')[0].appendChild(fileObj);
  72. } else {
  73. success();
  74. }
  75. }
  76. /*获取文件类型,后缀名,小写*/
  77. function GetFileType(url) {
  78. if (url != null && url.length > 0) {
  79. return url.substr(url.lastIndexOf(".")).toLowerCase();
  80. }
  81. return "";
  82. }
  83. /*文件是否已加载*/
  84. function FileIsExt(FileArray, _url) {
  85. if (FileArray != null && FileArray.length > 0) {
  86. var len = FileArray.length;
  87. for (var i = 0; i < len; i++) {
  88. if (FileArray[i] == _url) {
  89. return true;
  90. }
  91. }
  92. }
  93. return false;
  94. }
  95. };
  96. //获取页面url后面的参数
  97. Manage.prototype.number = function(variable) {
  98. var query = window.location.search.substring(1);
  99. var vars = query.split("&");
  100. for (var i=0;i<vars.length;i++) {
  101. var pair = vars[i].split("=");
  102. if(pair[0] == variable){return pair[1];}
  103. }
  104. return(false);
  105. };
  106. Manage.prototype.loadWeixin = function() {
  107. var that = this;
  108. this.LoadJs(that.weixinURL+that.time,function(){ });
  109. }
  110. Manage.prototype.loadAudio = function() { //相关:g_tourAudio \ g_playAudio
  111. g_bgAudio = new Audio;
  112. //g_bgAudio.loop = true;
  113. g_bgAudio.autoplay = true;
  114. g_bgAudio.id = "bgaudio";
  115. //https://www.cnblogs.com/interdrp/p/4211883.html 部分资料
  116. g_bgAudio.load(); // iOS 9 还需要额外的 load 一下, 否则直接 play 无效
  117. var play = function(){
  118. //if(window.tourAudioSta) return;
  119. this.musicShouldPlay && !g_tourAudio.shouldPlay && this.switchBgmState(true)
  120. document.removeEventListener("touchstart",play);
  121. document.removeEventListener("click",play);
  122. $('#player')[0].removeEventListener("touchstart", play);
  123. }.bind(this);
  124. g_bgAudio.oncanplay = ()=>{
  125. this.musicShouldPlay && !g_tourAudio.shouldPlay && this.switchBgmState(true)
  126. }
  127. document.addEventListener("WeixinJSBridgeReady", ()=> {
  128. this.musicShouldPlay && !g_tourAudio.shouldPlay && this.switchBgmState(true)
  129. }, false);
  130. document.addEventListener("touchstart", play);//ios需要加个事件才能播放 不能自动播放;如果还有浏览器不行,换成别的交互事件
  131. document.addEventListener("click", play);
  132. $('#player')[0].addEventListener("touchstart", play);
  133. g_bgAudio.addEventListener('ended', ()=>{
  134. //间隔5s
  135. setTimeout(()=>{
  136. this.musicShouldPlay && !g_tourAudio.shouldPlay && this.switchBgmState(true)
  137. },5000)
  138. });
  139. $("#volume").find("a").on("click", ()=> {
  140. if($("#volume img")[0].src.indexOf("btn_on.png")>-1)
  141. {
  142. this.switchMusicState(true);
  143. }
  144. else if($("#volume img")[0].src.indexOf("btn_off.png")>-1)
  145. {
  146. this.switchMusicState(false);
  147. }
  148. })
  149. }
  150. Manage.prototype.ifTourCanPlay = function(){//只有导览在播放时才能继续播放导览音频,如果是点击导览片段飞过去,一旦停止就不会再播
  151. return player.director && player.director.tourIsPlaying && player.director.getAudio()
  152. }
  153. Manage.prototype.switchMusicState = function(state){ //按钮按钮掌管全局音频,导览优先,没有了才放bgm
  154. this.musicShouldPlay = state
  155. if(state){
  156. if(! (this.ifTourCanPlay() && player.director.playAudio())){
  157. this.switchBgmState(true)
  158. }else{
  159. //this.currentPlay = 'tour'
  160. }
  161. $("#volume a img").attr("src", "./images/Volume btn_off.png")
  162. $("#volume").attr("title", "关闭声音");
  163. }else{
  164. g_tourAudio.pause()
  165. this.switchBgmState(false)
  166. $("#volume a img").attr("src", "./images/Volume btn_on.png")
  167. $("#volume").attr("title", "打开声音");
  168. }
  169. }
  170. Manage.prototype.switchBgmState = function(state){
  171. if(!g_bgAudio || !g_bgAudio.src) return;
  172. this.currentPlay = 'bgm'
  173. var played = function(){
  174. console.log('begin play bgm '+ g_bgAudio.src);
  175. g_play = 1;
  176. g_playAudio = g_bgAudio;
  177. g_tourAudio && g_tourAudio.pause()
  178. //SoundOnVideo && switchSoundBtn(SoundOnVideo)
  179. }
  180. var paused = function(){
  181. g_play = 0;
  182. g_playAudio == g_bgAudio && (g_playAudio = null)
  183. }
  184. if(state ){
  185. g_bgAudio.play();
  186. if(g_bgAudio.paused){
  187. paused()
  188. }else{
  189. played()
  190. return true
  191. }
  192. }else{
  193. g_bgAudio.pause();
  194. paused()
  195. }
  196. g_bgAudio.pauseByHot = false
  197. g_bgAudio.pauseByTour = false
  198. g_bgAudio.pauseByVideo = false
  199. }
  200. Manage.prototype.weixinShare = function() {
  201. console.log("weixinShare")
  202. $.ajax({
  203. url:'https://www.4dage.com/wechat/jssdk/',
  204. type: "post",
  205. data : {
  206. 'url' : location.href.split('#')[0]
  207. },
  208. dataType:"jsonp",
  209. jsonpCallback:"success_jsonp",
  210. success:function(data,textStatus){
  211. console.log("weixinShare success")
  212. console.log(data.appId)
  213. wx.config({
  214. // debug : true,
  215. appId : data.appId,
  216. timestamp : data.timestamp,
  217. nonceStr : data.nonceStr,
  218. signature : data.signature,
  219. jsApiList : [ 'checkJsApi', 'onMenuShareTimeline',
  220. 'onMenuShareAppMessage', 'onMenuShareQQ',
  221. 'onMenuShareWeibo', 'hideMenuItems',
  222. 'showMenuItems', 'hideAllNonBaseMenuItem',
  223. 'showAllNonBaseMenuItem', 'translateVoice',
  224. 'startRecord', 'stopRecord', 'onRecordEnd',
  225. 'playVoice', 'pauseVoice', 'stopVoice',
  226. 'uploadVoice', 'downloadVoice', 'chooseImage',
  227. 'previewImage', 'uploadImage', 'downloadImage',
  228. 'getNetworkType', 'openLocation', 'getLocation',
  229. 'hideOptionMenu', 'showOptionMenu', 'closeWindow',
  230. 'scanQRCode', 'chooseWXPay',
  231. 'openProductSpecificView', 'addCard', 'chooseCard',
  232. 'openCard' ]
  233. });
  234. },
  235. error:function(XMLHttpRequest,textStatus,errorThrown){
  236. console.log("jsonp.error:"+textStatus);
  237. }
  238. });
  239. var success_jsonp = function(json){
  240. console.log(json);
  241. };
  242. wx.ready(function(){
  243. // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行〿
  244. //对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中〿
  245. //分享到朋友圈
  246. console.log(g_weixinObj)
  247. wx.onMenuShareTimeline({
  248. title: g_weixinObj.title, // 分享标题
  249. link: g_weixinObj.lineLink, // 分享链接
  250. imgUrl: g_weixinObj.imgUrl, // 分享图标
  251. desc: g_weixinObj.desc
  252. });
  253. //获取“分享给朋友”按钮点击状态及自定义分享内容接叿
  254. wx.onMenuShareAppMessage({
  255. title: g_weixinObj.title, // 分享标题
  256. desc: g_weixinObj.desc, // 分享描述
  257. link: g_weixinObj.lineLink, // 分享链接
  258. imgUrl: g_weixinObj.imgUrl, // 分享图标
  259. type: '', // 分享类型,music、video或link,不填默认为link
  260. dataUrl: '' // 如果type是music或video,则要提供数据链接,默认为空
  261. });
  262. wx.onMenuShareWeibo({
  263. title: g_weixinObj.title, // 分享标题
  264. desc: g_weixinObj.desc, // 分享描述
  265. link: g_weixinObj.lineLink, // 分享链接
  266. imgUrl: g_weixinObj.imgUrl, // 分享图标
  267. success: function () {
  268. // 用户确认分享后执行的回调函数
  269. },
  270. cancel: function () {
  271. // 用户取消分享后执行的回调函数
  272. }
  273. });
  274. wx.onMenuShareQZone({
  275. title: g_weixinObj.title, // 分享标题
  276. desc: g_weixinObj.desc, // 分享描述
  277. link: g_weixinObj.lineLink, // 分享链接
  278. imgUrl: g_weixinObj.imgUrl, // 分享图标
  279. success: function () {
  280. // 用户确认分享后执行的回调函数
  281. },
  282. cancel: function () {
  283. // 用户取消分享后执行的回调函数
  284. }
  285. });
  286. wx.onMenuShareQQ({
  287. title: g_weixinObj.title, // 分享标题
  288. desc: g_weixinObj.desc, // 分享描述
  289. link: g_weixinObj.lineLink, // 分享链接
  290. imgUrl: g_weixinObj.imgUrl, // 分享图标
  291. success: function () {
  292. // 用户确认分享后执行的回调函数
  293. },
  294. cancel: function () {
  295. // 用户取消分享后执行的回调函数
  296. }
  297. });
  298. wx.error(function(res){
  299. // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名〿
  300. });
  301. });
  302. }
  303. Manage.prototype.dealURL = function(src, type){
  304. //music: "///super.4dage.com/data/LYW/edit/20200928_151633415.mp3"
  305. //"https://super.4dage.com/data/LYW/edit/20200928_165319399.jpg"]
  306. if(window.isLocal && settings.localPrefix!=void 0){//本地将线上的前缀替换
  307. var oldPrefixs = ["https://super.4dage.com/", "http://super.4dage.com/", "///super.4dage.com/"]
  308. for(let i=0;i<oldPrefixs.length;i++){
  309. if(src.includes(oldPrefixs[i])){
  310. return src.replace(oldPrefixs[i], settings.localPrefix)
  311. break;
  312. }
  313. }
  314. console.error("没有找到合适的本地链接")
  315. return src
  316. }else{
  317. return src
  318. }
  319. }
  320. var manage = new Manage();
  321. //公用的函数
  322. function getQueryVariable(variable)
  323. {
  324. var query = window.location.search.substring(1);
  325. var vars = query.split("&");
  326. for (var i=0;i<vars.length;i++) {
  327. var pair = vars[i].split("=");
  328. if(pair[0] == variable){return pair[1];}
  329. }
  330. return(false);
  331. }
  332. //隐藏公司Logo
  333. function showLogo(){
  334. $("#myCompany").hide();
  335. $("#loaderCoBrandName").hide();
  336. $("#title-logo").hide();
  337. $(".title-container").css("justify-content","center")
  338. }
  339. //czj 添加随机的时间
  340. function randomTime(){
  341. return new Date()
  342. };
  343. function matcher(data){
  344. if(!data || !g_version ) return data;
  345. delete data.model.vision_version;
  346. var _data = {
  347. files: {
  348. "templates": ["images/images{{number}}/{{filename}}"]
  349. },
  350. model :{
  351. sid :window.number,
  352. camera_start:
  353. data.model.images && data.model.images.length != 0 ?
  354. {
  355. camera: {
  356. zoom: "-1",
  357. quaternion: [
  358. JSON.parse(data.model.images[0].metadata).camera_quaternion.z,
  359. JSON.parse(data.model.images[0].metadata).camera_quaternion.w,
  360. JSON.parse(data.model.images[0].metadata).camera_quaternion.x,
  361. JSON.parse(data.model.images[0].metadata).camera_quaternion.y
  362. ]
  363. },
  364. pano: { uuid: JSON.parse(data.model.images[0].metadata).scan_id },
  365. mode: "0"
  366. }
  367. : ''
  368. },
  369. sid: window.number,
  370. hoticon: {
  371. default: "https://super.4dage.com/images/4dagePoint2.png",
  372. higt: "https://super.4dage.com/images/4dagePoint.png"
  373. },
  374. special: "false",
  375. weixinDesc: ""
  376. };
  377. $.extend(true,data,_data)
  378. return data;
  379. }
  380. function hotMatcher(data){
  381. if(!data || !g_version) return data;
  382. data.tourAudio = data.audio;
  383. return data;
  384. }
  385. var GifTexDeal = {
  386. animateObjects : [],
  387. addAnimation : function(texture, owner, info, id){
  388. var object = {
  389. texture,
  390. owner,
  391. info,
  392. id
  393. }
  394. this.setRepeart(object)
  395. this.animateObjects.push(object)
  396. return object
  397. },
  398. remove : function(object){
  399. var index = this.animateObjects.indexOf(object)
  400. if(index>-1){
  401. this.stop(object)
  402. object.texture.repeat.set(1,1)
  403. this.animateObjects.splice(index, 1)
  404. }
  405. },
  406. setRepeart : function(object){
  407. object.texture.repeat.set(1/object.info.cellXcount, 1/object.info.cellYcount)
  408. },
  409. start: function(object){
  410. /* var b = this
  411. , offset = this.cursor.material.map.offset
  412. , f = function(a) {
  413. return Math.floor(17 * a) / 17 //对应17个精灵图片段
  414. };
  415. b.canStartAnimation = !1,
  416. this.cursorAnimate = new TWEEN.Tween(offset).to({
  417. x: 1 //100%
  418. }, 1e3).onStart(function() {
  419. b.canStartAnimation = !1
  420. }).onStop(function() {
  421. b.canStartAnimation = !0,
  422. this.x = 0,
  423. offset.x = 0
  424. }).onUpdate(function() {}).onComplete(function() {
  425. done(),
  426. offset.x = 0,
  427. setTimeout(function() {
  428. b.canStartAnimation = !0
  429. }, 1500)
  430. }),
  431. this.cursorAnimate.easing(f),
  432. this.cursorAnimate.start()
  433. */
  434. if(!object || object.started)return;
  435. var count = object.info.cellXcount * object.info.cellYcount
  436. if(count == 1 )return;
  437. transitions.start( (progress)=>{
  438. var index = Math.floor(count * progress);
  439. var indexX = index % object.info.cellXcount
  440. var indexY = object.info.cellYcount - Math.floor(index / object.info.cellXcount ) - 1; //uv.offset.y是从下到上的
  441. object.texture.offset.x = indexX / object.info.cellXcount;
  442. object.texture.offset.y = indexY / object.info.cellYcount;
  443. //console.log(object.id + " : "+ object.texture.offset.toArray())
  444. } , object.info.duration, ()=>{//done
  445. object.started = false
  446. object.texture.offset.x = 0;
  447. object.texture.offset.y = 0;
  448. this.start(object)
  449. }, 0 ,null, object.id, "gif_"+object.id);
  450. object.started = true
  451. },
  452. startAnimations : function(o={}){
  453. this.animateObjects.forEach(e=>{this.start(e)})
  454. }
  455. ,
  456. stop: function(object){
  457. if(!object || !object.started)return;
  458. transitions.cancelById("gif_"+object.id);
  459. object.texture.offset.set(0,0)
  460. object.started = false
  461. }
  462. }
  463. var CloneObject = function(copyObj, result, isSimpleCopy) {
  464. //isSimpleCopy只复制最外层
  465. //复制json result的可能:普通数字或字符串、普通数组、复杂对象
  466. if(!copyObj)return null
  467. result = result || {};
  468. if (copyObj instanceof Array) {
  469. if (copyObj[0]instanceof Object) {
  470. //不支持含有 [[Object]] 这样二级数组里面还是复杂数据的,普通和复杂的数据混合可能也不支持
  471. console.error("不支持含有 [[Object]] 这样二级数组里面还是复杂数据的...")
  472. }
  473. return copyObj.slice(0);
  474. //如果是数组,直接复制返回(排除数组内是object
  475. }
  476. for (var key in copyObj) {
  477. if (copyObj[key]instanceof Object && !isSimpleCopy)
  478. result[key] = CloneObject(copyObj[key]);
  479. else
  480. result[key] = copyObj[key];
  481. //如果是函数类同基本数据,即复制引用
  482. }
  483. return result;
  484. }
  485. ;
  486. //兼容一代的場景
  487. //請求地址統一管理
  488. var g_onePregix = "https://bigscene.4dage.com/" //对应一代 http://www.4dmodel.com/SuperPanoramic/index.html?m=55
  489. var g_version = manage.number("version");
  490. g_version === "one" ? g_Prefix = g_onePregix : '';