manage.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  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.loadWeixin();
  7. }
  8. //动态加载js文件
  9. Manage.prototype.LoadJs = function(_files, succes){
  10. /* 已加载文件缓存列表,用于判断文件是否已加载过,若已加载则不再次加载*/
  11. var classcodes = [];
  12. var FileArray = [];
  13. if (typeof _files === "object") {
  14. FileArray = _files;
  15. } else {
  16. /*如果文件列表是字符串,则用,切分成数组*/
  17. if (typeof _files === "string") {
  18. FileArray = _files.split(",");
  19. }
  20. }
  21. if (FileArray != null && FileArray.length > 0) {
  22. var LoadedCount = 0;
  23. for (var i = 0; i < FileArray.length; i++) {
  24. loadFile(FileArray[i], function() {
  25. LoadedCount++;
  26. if (LoadedCount == FileArray.length) {
  27. try {
  28. succes();
  29. }
  30. catch(err) {
  31. console.log("err: 您未定义回调");
  32. }
  33. }
  34. })
  35. }
  36. }
  37. /*加载JS文件,url:文件路径,success:加载成功回调函数*/
  38. function loadFile(url, success) {
  39. if (!FileIsExt(classcodes, url)) {
  40. var _ThisType = GetFileType(url);
  41. var ThisType = _ThisType.indexOf("?") == -1 ? _ThisType : _ThisType.substring(0,_ThisType.indexOf("?"));
  42. var fileObj = null;
  43. if (ThisType == ".js") {
  44. fileObj = document.createElement('script');
  45. fileObj.src = url;
  46. } else if (ThisType == ".css") {
  47. fileObj = document.createElement('link');
  48. fileObj.href = url;
  49. fileObj.type = "text/css";
  50. fileObj.rel = "stylesheet";
  51. } else if (ThisType == ".less") {
  52. fileObj = document.createElement('link');
  53. fileObj.href = url;
  54. fileObj.type = "text/css";
  55. fileObj.rel = "stylesheet/less";
  56. }
  57. success = success || function() {};
  58. fileObj.onload = fileObj.onreadystatechange = function() {
  59. if (!this.readyState || 'loaded' === this.readyState || 'complete' === this.readyState) {
  60. success();
  61. classcodes.push(url)
  62. }
  63. }
  64. document.getElementsByTagName('head')[0].appendChild(fileObj);
  65. } else {
  66. success();
  67. }
  68. }
  69. /*获取文件类型,后缀名,小写*/
  70. function GetFileType(url) {
  71. if (url != null && url.length > 0) {
  72. return url.substr(url.lastIndexOf(".")).toLowerCase();
  73. }
  74. return "";
  75. }
  76. /*文件是否已加载*/
  77. function FileIsExt(FileArray, _url) {
  78. if (FileArray != null && FileArray.length > 0) {
  79. var len = FileArray.length;
  80. for (var i = 0; i < len; i++) {
  81. if (FileArray[i] == _url) {
  82. return true;
  83. }
  84. }
  85. }
  86. return false;
  87. }
  88. };
  89. //获取页面url后面的参数
  90. Manage.prototype.number = function(variable) {
  91. var query = window.location.search.substring(1);
  92. var vars = query.split("&");
  93. for (var i=0;i<vars.length;i++) {
  94. var pair = vars[i].split("=");
  95. if(pair[0] == variable){return pair[1];}
  96. }
  97. return(false);
  98. };
  99. Manage.prototype.loadWeixin = function() {
  100. var that = this;
  101. this.LoadJs(that.weixinURL+that.time,function(){ });
  102. }
  103. Manage.prototype.weixinShare = function() {
  104. console.log("weixinShare")
  105. $.ajax({
  106. url:'https://www.4dage.com/wechat/jssdk/',
  107. type: "post",
  108. data : {
  109. 'url' : location.href.split('#')[0]
  110. },
  111. dataType:"jsonp",
  112. jsonpCallback:"success_jsonp",
  113. success:function(data,textStatus){
  114. console.log("weixinShare success")
  115. console.log(data.appId)
  116. wx.config({
  117. // debug : true,
  118. appId : data.appId,
  119. timestamp : data.timestamp,
  120. nonceStr : data.nonceStr,
  121. signature : data.signature,
  122. jsApiList : [ 'checkJsApi', 'onMenuShareTimeline',
  123. 'onMenuShareAppMessage', 'onMenuShareQQ',
  124. 'onMenuShareWeibo', 'hideMenuItems',
  125. 'showMenuItems', 'hideAllNonBaseMenuItem',
  126. 'showAllNonBaseMenuItem', 'translateVoice',
  127. 'startRecord', 'stopRecord', 'onRecordEnd',
  128. 'playVoice', 'pauseVoice', 'stopVoice',
  129. 'uploadVoice', 'downloadVoice', 'chooseImage',
  130. 'previewImage', 'uploadImage', 'downloadImage',
  131. 'getNetworkType', 'openLocation', 'getLocation',
  132. 'hideOptionMenu', 'showOptionMenu', 'closeWindow',
  133. 'scanQRCode', 'chooseWXPay',
  134. 'openProductSpecificView', 'addCard', 'chooseCard',
  135. 'openCard' ]
  136. });
  137. },
  138. error:function(XMLHttpRequest,textStatus,errorThrown){
  139. console.log("jsonp.error:"+textStatus);
  140. }
  141. });
  142. var success_jsonp = function(json){
  143. console.log(json);
  144. };
  145. wx.ready(function(){
  146. // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行〿
  147. //对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中〿
  148. //分享到朋友圈
  149. console.log(g_weixinObj)
  150. wx.onMenuShareTimeline({
  151. title: g_weixinObj.title, // 分享标题
  152. link: g_weixinObj.lineLink, // 分享链接
  153. imgUrl: g_weixinObj.imgUrl, // 分享图标
  154. desc: g_weixinObj.desc
  155. });
  156. //获取“分享给朋友”按钮点击状态及自定义分享内容接叿
  157. wx.onMenuShareAppMessage({
  158. title: g_weixinObj.title, // 分享标题
  159. desc: g_weixinObj.desc, // 分享描述
  160. link: g_weixinObj.lineLink, // 分享链接
  161. imgUrl: g_weixinObj.imgUrl, // 分享图标
  162. type: '', // 分享类型,music、video或link,不填默认为link
  163. dataUrl: '' // 如果type是music或video,则要提供数据链接,默认为空
  164. });
  165. wx.onMenuShareWeibo({
  166. title: g_weixinObj.title, // 分享标题
  167. desc: g_weixinObj.desc, // 分享描述
  168. link: g_weixinObj.lineLink, // 分享链接
  169. imgUrl: g_weixinObj.imgUrl, // 分享图标
  170. success: function () {
  171. // 用户确认分享后执行的回调函数
  172. },
  173. cancel: function () {
  174. // 用户取消分享后执行的回调函数
  175. }
  176. });
  177. wx.onMenuShareQZone({
  178. title: g_weixinObj.title, // 分享标题
  179. desc: g_weixinObj.desc, // 分享描述
  180. link: g_weixinObj.lineLink, // 分享链接
  181. imgUrl: g_weixinObj.imgUrl, // 分享图标
  182. success: function () {
  183. // 用户确认分享后执行的回调函数
  184. },
  185. cancel: function () {
  186. // 用户取消分享后执行的回调函数
  187. }
  188. });
  189. wx.onMenuShareQQ({
  190. title: g_weixinObj.title, // 分享标题
  191. desc: g_weixinObj.desc, // 分享描述
  192. link: g_weixinObj.lineLink, // 分享链接
  193. imgUrl: g_weixinObj.imgUrl, // 分享图标
  194. success: function () {
  195. // 用户确认分享后执行的回调函数
  196. },
  197. cancel: function () {
  198. // 用户取消分享后执行的回调函数
  199. }
  200. });
  201. wx.error(function(res){
  202. // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名〿
  203. });
  204. });
  205. }
  206. Manage.prototype.dealURL = function(src, type){
  207. //music: "///super.4dage.com/data/LYW/edit/20200928_151633415.mp3"
  208. //"https://super.4dage.com/data/LYW/edit/20200928_165319399.jpg"]
  209. if(window.isLocal && settings.localPrefix!=void 0){//本地将线上的前缀替换
  210. var oldPrefix = 'super.4dage.com/'; //最简单的地址写一个,如果有其他完全不一样的地址就用数组逐个判断
  211. var index = src.indexOf(oldPrefix);
  212. if(index>-1){
  213. var wholeOldPrefix = src.slice(0, index+oldPrefix.length);
  214. return src.replace(wholeOldPrefix, settings.localPrefix)
  215. }
  216. console.error("没有找到合适的本地链接")
  217. return src
  218. }else{
  219. //add https://
  220. var prefix = g_Prefix.replace('https://','').replace('http://','')
  221. if(!src.includes('http:/') && !src.includes('https:/') && src.includes(prefix)){
  222. src = 'https://'+src
  223. }
  224. return src
  225. }
  226. }
  227. Manage.prototype.removeSrcPostMark = function(url){//去除texture.load时自动加上的'?'
  228. var index = url.indexOf('?')
  229. if(index>-1){
  230. return url.slice(0, index)
  231. }else return url
  232. }
  233. Manage.prototype.showInfo = function (o) { // ({result:true, title:"发布成功"});
  234. var box = $(".resultBox");
  235. var title = o.title || o || i18n.get('保存成功');
  236. box.children().eq(0).html(title)
  237. //var time = o.time || THREE.Math.clamp((Config.lang=='en') ? title.length*50 : title.length*130 ,1300,5000);
  238. var time = o.time || THREE.Math.clamp(title.length*130 ,1300, 5000);
  239. o.time || console.log("showtime " + time)
  240. //实际有一半的时间在渐变透明度
  241. this.showInfoTimer && clearTimeout(this.showInfoTimer)
  242. box.removeClass("animate");//如果之后不久又要showinfo一个的话,先停止前面的animate
  243. setTimeout(function () {
  244. box.css(
  245. {
  246. '-webkit-animation-duration': time + 'ms',
  247. 'animation-duration': time + 'ms'
  248. }
  249. )
  250. if(o.top){
  251. box.children().css('top', o.top + "%");
  252. }else{
  253. box.children().css('top', '' )
  254. }
  255. box.removeClass("hide");
  256. box.addClass("animate");
  257. if (o.dontInteract) {//遮挡对屏幕的操作
  258. box.css('pointer-events', 'auto')
  259. } else {
  260. box.css('pointer-events', 'none')
  261. }
  262. this.showInfoTimer = setTimeout(function () {
  263. box.removeClass("animate");
  264. box.addClass("hide");
  265. this.showInfoTimer = null;
  266. }.bind(this), time + 20)
  267. }.bind(this), 50)//这个数字太小的话后面触发的没有重新animate的效果 应该要比帧率大吧
  268. }//like: manage.showInfo({title:'a', top:20})
  269. //公用的函数
  270. function getQueryVariable(variable)
  271. {
  272. var query = window.location.search.substring(1);
  273. var vars = query.split("&");
  274. for (var i=0;i<vars.length;i++) {
  275. var pair = vars[i].split("=");
  276. if(pair[0] == variable){return pair[1];}
  277. }
  278. return(false);
  279. }
  280. //隐藏公司Logo
  281. function showLogo(){
  282. $("#myCompany").hide();
  283. $("#loaderCoBrandName").hide();
  284. $("#title-logo").hide();
  285. $(".title-container").css("justify-content","center")
  286. }
  287. //czj 添加随机的时间
  288. function randomTime(){
  289. return new Date()
  290. };
  291. function matcher(data){
  292. if(!data || !g_version ) return data;
  293. delete data.model.vision_version;
  294. var _data = {
  295. files: {
  296. "templates": ["images/images{{number}}/{{filename}}"]
  297. },
  298. model :{
  299. sid :window.number,
  300. camera_start:
  301. data.model.images && data.model.images.length != 0 ?
  302. {
  303. camera: {
  304. zoom: "-1",
  305. quaternion: [
  306. JSON.parse(data.model.images[0].metadata).camera_quaternion.z,
  307. JSON.parse(data.model.images[0].metadata).camera_quaternion.w,
  308. JSON.parse(data.model.images[0].metadata).camera_quaternion.x,
  309. JSON.parse(data.model.images[0].metadata).camera_quaternion.y
  310. ]
  311. },
  312. pano: { uuid: JSON.parse(data.model.images[0].metadata).scan_id },
  313. mode: "0"
  314. }
  315. : ''
  316. },
  317. sid: window.number,
  318. hoticon: {
  319. default: "https://super.4dage.com/images/4dagePoint2.png",
  320. higt: "https://super.4dage.com/images/4dagePoint.png"
  321. },
  322. special: "false",
  323. weixinDesc: ""
  324. };
  325. $.extend(true,data,_data)
  326. return data;
  327. }
  328. function hotMatcher(data={}){
  329. //if(!data || !g_version) return data;
  330. if(g_version) {
  331. data.tourAudio = data.audio || {};
  332. }else{
  333. data.tourAudio = {}
  334. }
  335. return data;
  336. }
  337. var GifTexDeal = {
  338. animateObjects : [],
  339. animateTexs : [] ,
  340. addAnimation : function(texture, owner, info, id){
  341. /* if(this.animateObjects.find(e=>
  342. e.texture == texture && !ifSame(info, e.info)
  343. )) */
  344. var animation
  345. var tex = this.animateTexs.find(e=>e.texture == texture)
  346. if(tex){
  347. animation = tex
  348. }else{
  349. animation = {texture,info }
  350. this.animateTexs.push(animation)
  351. this.setRepeart(animation)
  352. }
  353. var object = {
  354. animation, //默认相同的texture对应的info是一样的, 对应一个animation
  355. owner,
  356. }
  357. this.animateObjects.push(object)
  358. return object
  359. },
  360. remove : function(object){
  361. var index = this.animateObjects.indexOf(object)
  362. if(index>-1){
  363. this.animateObjects.splice(index, 1)
  364. if(!this.animateObjects.find(e=>e.animation == object.animation)){
  365. let i = this.animateTexs.indexOf(object.animation)
  366. this.animateTexs.splice(i, 1)
  367. object.animation.texture.repeat.set(1,1)
  368. }
  369. this.stop(object)
  370. }
  371. },
  372. setRepeart : function(animation){
  373. animation.texture.repeat.set(1/animation.info.cellXcount, 1/animation.info.cellYcount)
  374. },
  375. start: function(object){
  376. if(!object || object.started )return;
  377. object.started = true
  378. if(object.animation.started)return;
  379. object.animation.started = true
  380. var info = object.animation.info
  381. var count = info.cellXcount * info.cellYcount - (info.voidCount || 0)
  382. if(count <= 1)return;
  383. transitions.start( (progress)=>{
  384. var index = Math.floor(count * progress);
  385. var indexX = index % info.cellXcount
  386. var indexY = info.cellYcount - Math.floor(index /info.cellXcount ) - 1; //uv.offset.y是从下到上的
  387. object.animation.texture.offset.x = indexX / info.cellXcount;
  388. object.animation.texture.offset.y = indexY / info.cellYcount;
  389. //console.log(object.id + " : "+ object.texture.offset.toArray())
  390. } , info.duration * (-1), null,/* ()=>{//done (-1):循环
  391. object.started = false
  392. object.texture.offset.x = 0;
  393. object.texture.offset.y = 0;
  394. this.start(object)
  395. }, */ 0 ,null, object.id, "gif_"+object.animation.texture.id);
  396. },
  397. stop: function(object){
  398. if(!object || !object.started)return;
  399. object.started = false
  400. //只有该object对应的texture对应的所有object都停止了,才能真的停止动画:
  401. if(this.animateObjects.find(e=>e.animation == object.animation && e.started)) return;
  402. transitions.cancelById("gif_"+object.animation.texture.id);
  403. object.animation.texture.offset.set(0,0)
  404. object.animation.started = false
  405. }
  406. }
  407. var CloneObject = function(copyObj, result, isSimpleCopy, extraReplace) {
  408. //isSimpleCopy只复制最外层
  409. //复制json result的可能:普通数字或字符串、普通数组、复杂对象
  410. if(!copyObj)return copyObj //0 null undefined ''
  411. result = result || {};
  412. if (copyObj instanceof Array) {
  413. /* if (copyObj[0]instanceof Object) {
  414. //不支持含有 [[Object]] 这样二级数组里面还是复杂数据的,普通和复杂的数据混合可能也不支持
  415. console.error("不支持含有 [[Object]] 这样二级数组里面还是复杂数据的...")
  416. }
  417. return copyObj.slice(0);*/ //如果是数组,直接复制返回(排除数组内是object
  418. return copyObj.map(e=>{
  419. if(e instanceof Object){
  420. return CloneObject(e)
  421. }else return e
  422. })
  423. }else{
  424. if(copyObj.clone instanceof Function ){ //解决一部分
  425. return copyObj.clone()
  426. }
  427. }
  428. for (var key in copyObj) {
  429. if (copyObj[key] instanceof Object && !isSimpleCopy)
  430. result[key] = CloneObject(copyObj[key]);
  431. else
  432. result[key] = copyObj[key];
  433. //如果是函数类同基本数据,即复制引用
  434. }
  435. return result;
  436. }
  437. ;
  438. var ifSame = function(object1, object2){
  439. if(object1 == object2 )return true // 0 != undefined , 0 == ''
  440. else if(!object1 || !object2) return false
  441. else if(object1.constructor != object2.constructor){
  442. return false
  443. }else if(object1 instanceof Array ) {
  444. if(object1.length != object2.length)return false;
  445. var _object2 = object2.slice(0);
  446. for(let i=0;i<object1.length;i++){
  447. var u = _object2.find(e=>ifSame(object1[i], e));
  448. if(u == void 0 && !_object2.includes(u) && !object1.includes(u))return false;
  449. else{
  450. let index = _object2.indexOf(u);
  451. _object2.splice(index,1);
  452. }
  453. }
  454. return true
  455. }else if(object1.equals instanceof Function ){//复杂数据仅支持这种,其他的可能卡住?
  456. return object1.equals(object2)
  457. }else if(typeof object1 == 'number' || typeof object1 == 'string'){
  458. if(isNaN(object1) && isNaN(object2))return true
  459. else return object1 == object2
  460. }else if(typeof object1 == "object"){
  461. var keys1 = Object.keys(object1)
  462. var keys2 = Object.keys(object2)
  463. if(!ifSame(keys1,keys2))return false;
  464. for(let i in object1){
  465. var same = ifSame(object1[i], object2[i]);
  466. if(!same)return false
  467. }
  468. return true
  469. }else{
  470. console.log('isSame出现例外')
  471. }
  472. }
  473. /* var SoundManager = {//暂不支持同时播放
  474. currentAudio:null,//当前正在播放list中的哪一个
  475. list:[
  476. {
  477. name:"bg",
  478. level : 0,//越大优先级越高
  479. canBeInterrupted : true ,
  480. },
  481. {
  482. name:"boxVideo",
  483. level : 1,
  484. canBeInterrupted : true,
  485. checkIfNeedPlay:function(){
  486. }
  487. },
  488. {
  489. name:"hot",
  490. level : 2,
  491. canBeInterrupted : true
  492. },
  493. {
  494. name:"tour",
  495. level : 3,
  496. canBeInterrupted : true
  497. },
  498. ],
  499. switchPlay:function(){
  500. },
  501. register:function(){
  502. }
  503. }
  504. */
  505. //最好能知道应该播放到的currentTime
  506. var SoundManager = {//暂不支持同时播放
  507. currentAudio:null,//当前正在播放list中的哪一个
  508. enableSound:true,//是否允许有声音
  509. playHistory:[],
  510. list:[ //同一级别可以互相打断 //暂时不做多级别
  511. ],
  512. play:function(name, src, currentTime){
  513. var object = this.list.find(e=>e.name == name)
  514. if(object){
  515. if(this.currentAudio){
  516. this.pause(this.currentAudio.name, false, true)
  517. }
  518. {//将当前要播放的播放历史中清除
  519. let index = this.playHistory.indexOf(object)
  520. if(index>-1)this.playHistory.splice(index,1);
  521. }
  522. this.currentAudio = object
  523. if(src){
  524. this.setSrc(name, src)
  525. }
  526. if(currentTime!=void 0){
  527. object.audio.currentTime = currentTime
  528. }
  529. if(object.audio){
  530. object.audio.load(); // iOS 9 还需要额外的 load 一下, 否则直接 play 无效 *///https://www.cnblogs.com/interdrp/p/4211883.html 部分资料
  531. object.audio.play();
  532. object.callback && object.callback(true)
  533. }
  534. Log(name + ' 播放 ' )
  535. }
  536. },
  537. pause:function(name, autoReplayLast, isInterrupt){//需要能自动恢复上一个被打算的音频。恢复前判断是否还需要播放
  538. var object = this.list.find(e=>e.name == name)
  539. if(object){
  540. this.currentAudio = null
  541. if(object.audio){
  542. object.audio.pause()
  543. object.callback && object.callback(false)
  544. Log(name + ' 中断音频 '+ "("+common.getFileNameFromUrl(object.audio.src)+')' )
  545. }
  546. if(isInterrupt){//一般主动调用不需要加这个
  547. this.playHistory.push(object)//如果是被中断的,加入播放历史,等待恢复播放
  548. }
  549. if(autoReplayLast){ //播放之前的音频。它们是被打断过的。
  550. while(this.playHistory.length){
  551. var last = this.playHistory.pop();
  552. if(last.src && last.canplay(last.audio)){
  553. this.play(last.name )
  554. }
  555. }
  556. }
  557. }
  558. },
  559. /* resume:function(){ //比如热点关闭后继续播放bgm
  560. }, */
  561. setSrc : function(name, src){//不能直接给audio赋src!一定要用这个函数!因为我要拿这里的src来判断有无src,因为貌似audio的src会自动变,''时会变成html的链接
  562. var object = this.list.find(e=>e.name == name)
  563. object.src = src
  564. object.audio.src = src
  565. Log(`${object.name} 设置src: ${src}`)
  566. },
  567. createAudio:function(object={}){//name, level, canplay
  568. if(!object.fake){
  569. object.audio = new Audio();
  570. object.audio.loop = !!object.loop;
  571. //object.audio.autoplay = true;
  572. object.audio.addEventListener('ended', ()=>{
  573. if(object.loop){//循环
  574. Log(`${object.name} 播放完毕,重新播放`)
  575. object.audio.play()
  576. }else{
  577. this.pause(object.name, true);//停止后的后续处理
  578. }
  579. });
  580. object.audio.oncanplaythrough = ()=>{
  581. Log(`${object.name} canplaythrough `)
  582. }
  583. }
  584. this.list.push(object)
  585. },
  586. initAutoPlay:function(){
  587. let play = function(){
  588. if(this.currentAudio && this.currentAudio.audio){
  589. this.currentAudio.audio.play()
  590. Log(`${this.currentAudio.name} 自动播放成功`) //即使设置src在这之后好像也能成功播放
  591. }else{
  592. }
  593. document.removeEventListener("touchstart",play);
  594. document.removeEventListener("click",play);
  595. $('#player')[0].removeEventListener("touchstart", play);
  596. }.bind(this);
  597. document.addEventListener("WeixinJSBridgeReady", play, false);
  598. document.addEventListener("touchstart", play);//ios需要加个事件才能播放 不能自动播放;如果还有浏览器不行,换成别的交互事件
  599. document.addEventListener("click", play);
  600. $('#player')[0].addEventListener("touchstart", play);
  601. }
  602. }
  603. function Log(value, color, fontSize){
  604. color = color || '#13f'
  605. fontSize = fontSize || 14
  606. console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`)
  607. }
  608. Manage.prototype.loadAudio = function() { //相关:g_tourAudio \ g_playAudio
  609. //热点页面因为挡住了界面,所以暂时不存在别的音频阻止热点音频的可能
  610. //box视频都静音,所以暂时不考虑
  611. SoundManager.createAudio({
  612. name:'bgm',
  613. level:0,
  614. src:'',
  615. loop:true,
  616. canplay:(audio)=>{
  617. return this.bgmShouldPlay
  618. },
  619. callback:(state)=>{//play或pause时随之触发的函数(即使还没开始播放)
  620. if(state){
  621. $("#volume a img").attr("src", "./images/Volume btn_off.png")
  622. $("#volume").attr("title", "关闭声音");
  623. }else{
  624. $("#volume a img").attr("src", "./images/Volume btn_on.png")
  625. $("#volume").attr("title", "打开声音");
  626. }
  627. }
  628. })
  629. SoundManager.createAudio({
  630. name:'tour',
  631. level:0,
  632. src:'',
  633. loop:false,
  634. canplay:(audio)=>{
  635. return player.director && player.director.tourIsPlaying && player.director.getAudio()
  636. }
  637. })
  638. SoundManager.createAudio({
  639. name:'hot',
  640. fake:true,//实际上没有audio. 只是为了来停止和续播其他音频
  641. level:1,
  642. src:'',
  643. loop:false,
  644. canplay:(audio)=>{
  645. }
  646. })
  647. $("#volume").find("a").on("click", ()=> {
  648. if($("#volume img")[0].src.indexOf("btn_on.png")>-1)
  649. {
  650. this.switchBgmState(true);
  651. }
  652. else if($("#volume img")[0].src.indexOf("btn_off.png")>-1)
  653. {
  654. this.switchBgmState(false);
  655. }
  656. })
  657. this.switchBgmState(true);//初始设置允许播放bgm
  658. SoundManager.initAutoPlay()
  659. }
  660. Manage.prototype.switchBgmState = function(state){//按钮的状态完全代表是否应该播放bgm,即使还没加载完
  661. this.bgmShouldPlay = state
  662. if(state){
  663. SoundManager.play('bgm')
  664. }else{
  665. SoundManager.pause('bgm')
  666. }
  667. /* if(!g_bgAudio || !g_bgAudio.src) return;
  668. var played = function(){
  669. console.log('begin play bgm');
  670. g_play = 1;
  671. g_playAudio = g_bgAudio;
  672. g_tourAudio && g_tourAudio.pause()
  673. }
  674. var paused = function(){
  675. g_play = 0;
  676. g_playAudio == g_bgAudio && (g_playAudio = null)
  677. }
  678. if(state ){
  679. g_bgAudio.play();
  680. if(g_bgAudio.paused){
  681. paused()
  682. }else{
  683. played()
  684. return true
  685. }
  686. }else{
  687. g_bgAudio.pause();
  688. paused()
  689. }
  690. g_bgAudio.pauseByHot = false
  691. g_bgAudio.pauseByTour = false */
  692. }
  693. var manage = new Manage();
  694. //兼容一代的場景
  695. //請求地址統一管理
  696. var g_onePregix = "https://bigscene.4dage.com/" //对应一代 http://www.4dmodel.com/SuperPanoramic/index.html?m=55
  697. var g_version = manage.number("version");
  698. g_version === "one" ? g_Prefix = g_onePregix : '';