var Map_QM, renderFrame = -1, pathCameraState, stats, isJUZ = false, iot = true, shopTime, debug = false; //basePath 基础路径 graphPath最佳路径 ftPath 扶梯路径 dtPath 电梯路径 var css_LR = "color:#000000;height: 16px;font-size: 14px; z-index: 90; text-shadow: 1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff; pointer-events:none;"; var typeObj = [{ ft: 0, type: 0, code: 'ft', name: '扶梯' }, { upft: 1, type: 1, code: 'upft', name: '上扶梯' }, { downft: 2, type: 2, code: 'downft', name: '下扶梯' }, { mys: 3, type: 3, code: 'mys', name: '母婴室' }, { xsj: 4, type: 4, code: 'xsj', name: '洗手间' }, { dt: 5, type: 5, code: 'dt', name: '直梯' }, { hxkj: 6, type: 6, code: 'hxkj', name: '焕醒空间' }, { fwt: 7, type: 7, code: 'fwt', name: '服务台' }, { tcc: 8, type: 8, code: 'tcc', name: '停车场' }, { hhkj: 9, type: 9, code: 'hhkj', name: '焕活空间' }, { cjr: 10, type: 10, code: 'cjr', name: '无障碍洗手间' }, { xys: 11, type: 11, code: 'xys', name: '吸烟室' }, { upft: 12, type: 12, code: 'upft', name: '上扶梯' }, { downft: 13, type: 13, code: 'downft', name: '下扶梯' }, { dkbc: 14, type: 14, code: 'dkbc', name: '代客泊车' }, { tczj: 15, type: 15, code: 'tczj', name: '童车租借' }, { ysc: 16, type: 16, code: 'ysc', name: '饮水处' }, { ztg: 17, type: 17, code: 'ztg', name: 'L1自提柜' }, { thg: 18, type: 18, code: 'thg', name: 'B1自提柜' }, { cwysd: 19, type: 19, code: 'cwysd', name: '宠物饮水点' }, { td: 20, type: 20, code: 'td', name: '人行通道' }, { dit: 21, type: 21, code: 'dit', name: '地铁' }, { czc: 22, type: 22, code: 'czc', name: '出租车' }, { atm: 23, type: 23, code: 'atm', name: 'ATM' }, { jcfw: 24, type: 24, code: 'jcfw', name: '寄存服务' }, { sjcd: 25, type: 25, code: 'sjcd', name: '手机充电' }, { bc: 26, type: 26, code: 'bc', name: '泊车' }, { cjc: 27, type: 27, code: 'cjc', name: '裁剪处' }, { jtn: 28, type: 28, code: 'jtn', name: '家庭洗手间(男)' }, { jtv: 29, type: 29, code: 'jtv', name: '家庭洗手间(女)' }, { ksgj: 30, type: 30, code: 'ksgj', name: '公交' }, { sjxsn: 31, type: 31, code: 'sjxsn', name: '无障碍洗手间男' }, { sjxsv: 32, type: 32, code: 'sjxsv', name: '无障碍洗手间女' }, { tcjf: 33, type: 33, code: 'tcjf', name: '停车缴费' }, { vip: 34, type: 34, code: 'vip', name: 'VIP' }, { xsjn: 35, type: 35, code: 'xsjn', name: '男洗手间' }, { xsjv: 36, type: 36, code: 'xsjv', name: '女洗手间' }, { yszj: 37, type: 37, code: 'yszj', name: '雨伞租借' }, { dyj: 38, type: 38, code: 'dyj', name: '打印机' }, { door: 39, type: 39, code: 'door', name: '出入口' }, { pq: 40, type: 40, code: 'pq', name: '喷泉' }, { d1k: 41, type: 41, code: 'd1k', name: '1号出入口' }, { d2k: 42, type: 42, code: 'd2k', name: '2号出入口' }, { d3k: 43, type: 43, code: 'd3k', name: '3号出入口' }, { d4k: 44, type: 44, code: 'd4k', name: '4号出入口' }, { mjzyf: 45, type: 45, code: 'mjzyf', name: '门急诊药房' }, { cryc: 46, type: 46, code: 'cryc', name: '出入院处' }, { rggh: 47, type: 47, code: 'rggh', name: '人工挂号收费处' }, { zzyl: 48, type: 48, code: 'zzyl', name: '自动饮料贩卖机' }, { gxly: 49, type: 49, code: 'gxly', name: '共享轮椅' }, { ysp: 50, type: 50, code: 'ysp', name: '艺术品' }, { B1up: 51, type: 51, code: 'B1up', name: '' }, { B1down: 52, type: 52, code: 'B1down', name: '' }, { B2up: 53, type: 53, code: 'B2up', name: '' }, { B2down: 54, type: 54, code: 'B2down', name: '' }, { B3up: 55, type: 55, code: 'B3up', name: '' }, { B3down: 56, type: 56, code: 'B3down', name: '' }, { xcgc: 57, type: 57, code: 'xcgc', name: '下沉广场' }, { tthy: 58, type: 58, code: 'tthy', name: '天台花园' }, { ybck: 59, type: 59, code: 'ybck', name: '医保窗口' }, { zzfw: 60, type: 60, code: 'zzfw', name: '自助服务' }, { gjj: 61, type: 61, code: 'gjj', name: '工具间' }, { syt1: 62, type: 62, code: 'syt1', name: 'mall收银台' }, { gwc: 63, type: 63, code: 'gwc', name: '购物车' }, { ht: 64, type: 64, code: 'ht', name: '花坛' }, { jrc: 65, type: 65, code: 'jrc', name: '自助加热' }, { qbc: 66, type: 66, code: 'qbc', name: '自助取冰' }, { zxc: 67, type: 67, code: 'zxc', name: '自行车停放' }, { jws: 68, type: 68, code: 'jws', name: '警务室' }, { etxsj: 69, type: 69, code: 'etxsj', name: '儿童洗手间' }, { vip_xxq: 70, type: 70, code: 'vip_xxq', name: 'vip休息区' }, { ab: 71, type: 71, code: 'ab', name: '安保' }, { abjks: 72, type: 72, code: 'abjks', name: '安保监控室' }, { bys: 73, type: 73, code: 'bys', name: '播音室' }, { cpgys: 74, type: 74, code: 'cpgys', name: '裁判更衣室' }, { gzyld: 75, type: 75, code: 'gzyld', name: '观众医疗点' }, { hqgys: 76, type: 76, code: 'hqgys', name: '后勤更衣室' }, { jjs: 77, type: 77, code: 'jjs', name: '急救室' }, { jw: 78, type: 78, code: 'jw', name: '警卫' }, { ksj: 79, type: 79, code: 'ksj', name: '开水间' }, { kt: 80, type: 80, code: 'kt', name: '看台' }, { qzgysn: 81, type: 81, code: 'qzgysn', name: '亲自更衣(男)' }, { rsggys: 82, type: 82, code: 'rsggys', name: '热身馆更衣室' }, { swzl: 83, type: 83, code: 'swzl', name: '失物招领' }, { tsgbs1: 84, type: 84, code: 'tsgbs1', name: '特殊贵宾室1' }, { tsgbs2: 85, type: 85, code: 'tsgbs2', name: '特殊贵宾室2' }, { tsgbs3: 86, type: 86, code: 'tsgbs3', name: '特殊贵宾室3' }, { wxc: 87, type: 87, code: 'wxc', name: '闻讯处' }, { lt: 88, type: 88, code: 'lt', name: '楼梯' }, { yhs: 89, type: 89, code: 'yhs', name: '医护室' }, { yls: 90, type: 90, code: 'yls', name: '医疗室' }, { ylz: 91, type: 91, code: 'ylz', name: '医疗站' }, { ydygys: 92, type: 92, code: 'ydygys', name: '运动员更衣室' }, { ydygysn: 93, type: 93, code: 'ydygysn', name: '运动员男更衣室' }, { ydygysv: 94, type: 94, code: 'ydygysv', name: '运动员女更衣室' }, { zls: 95, type: 95, code: 'zls', name: '诊疗室' }, { zys: 96, type: 96, code: 'zys', name: '直饮水' }, { zas: 97, type: 97, code: 'zas', name: '治安室' }, { xxq: 98, type: 98, code: 'xxq', name: '休息区' }, { jtxsj: 99, type: 99, code: 'jtxsj', name: '家庭洗手间' }, { hzs: 100, type: 100, code: 'hzs', name: '化妆室' }, { brs: 101, type: 101, code: 'brs', name: '哺乳室' }, { mtl: 102, type: 102, code: 'mtl', name: '摩天轮' }, { dgnxsj: 103, type: 103, code: 'dgnxsj', name: '多功能洗手间' }, { wxbxsj: 104, type: 104, code: 'wxbxsj', name: '无性别洗手间' }, { sjzx: 105, type: 105, code: 'sjzx', name: '设计中心' }, { dxp: 106, type: 106, code: 'dxp', name: '导向牌' }, { gydh: 107, type: 107, code: 'gydh', name: '公用电话' }, { sgq: 108, type: 108, code: 'sgq', name: '石拱桥' }, { wxw: 109, type: 109, code: 'wxw', name: '无线网' }, { xmb: 110, type: 110, code: 'xmb', name: '小卖部' }, { zyzfwz: 111, type: 111, code: 'zyzfwz', name: '志愿者服务站' }, { ykzx: 112, type: 112, code: 'ykzx', name: '服务中心' }, { zjyy: 113, type: 113, code: 'zjyy', name: '专家预约处' }, { yjt: 114, type: 114, code: 'yjt', name: '预检台' }, { mzjd: 115, type: 115, code: 'mzjd', name: '门诊综合接待室' }, { hd: 116, type: 116, code: 'hd', name: '活动点' }, { bsl: 117, type: 117, code: 'bsl', name: '白石龙' }]; QMUtil = function () { this.shopServerInfo = "static/offline/JSON/QueryShopList.json"; this.mapServerInfo = "static/offline/JSON/GetMapInfo.json"; this.beforPath = "./"; this.options = { playSpeed: 6, //动画播放速度 collision: true, //是否支持名称的碰撞检测 showStyle: false, //是否4K modelIcon: true, //是否使用模型 true 模型 false 图标 otherPath: [], //人为干预的路线 [{f:"0_5_10",s:"1_5_47",d:500},{f:"1_5_47",s:"0_5_10",d:500}]; bSpace: 5000, fSpace: 500, //双叠层状态下楼层的间距 maxDis: 1000, minDis: 60, shadow: true, //是否显示阴影 navColor: 0xEE6A50, //途径店铺颜色 aRadius: 2, //圆角半径 大于2 则店铺box显示圆角 overlap: false, //是否叠层 iconName: false, //图标名称是否显示 mapScale: 18, //地图比例尺 pathColor: 0xb47834, pathStyle: "3D", shopStyle: "shopName", //设置box显示名称shopName或编号shopNum inArea: false, //点击后是否聚焦到店铺 camZoom: 3, //设置我的方向状态地图放大倍数 boxShop: [], //设置box上显示的文字(过滤指),可点击触发onlyShop deviceAng: false, //地图初始化方向是否使用设备角度 } this.lightOptions = { d_col: "#ffffff", d_int: 0.2, s_col: "#fffffa", g_col: "#ffffff", a_int: 0.85 }; this._clock = new THREE.Clock(); this._indexPathFloor = 0; // 遍历途径数据 this.changeDist = { inner: 350, outner: 900 }; //室内外切换的极限值, 如果 inner小于minDis 则不支持缩放切换 /** * isPathState 寻路状态 */ this.pathStateObj = { isPathState: false, isPathPlay: true, basePath: "", graphPath: "", ftPath: "", dtPath: "", facAllArr: [], forShopArr: {}, elevator: null, straight: null, elevatorDown: null, seldtFacNo: "", seldownftFacNo: "", selupftFacNo: "" }; this.timeObj = { timeS: 0, collTime: -1, pathTime: -1 }; //debug 参数 相机坐标/ 镜头方向 this.guiOptions = { cameraX: -16, cameraY: 136, cameraZ: 146, targatX: -17, targatY: 0, targatZ: 20 }; //this.button = function() {}; this.sceneGap = { x: 0, y: 0, z: 0, scale: 0.09 }; //改变地图位置,大小 this.selectBuild = 0; this.selectFloor = 0; this.deviceObj = {}; //angle --- 设备旋转角度 node ---- 设备导航点位 floor --- 设备楼层 this.startObj = {}; // 导航起点; this.overObj = {}; //导航结束点 this.tubeMaterial = new THREE.MeshPhongMaterial({ color: this.options.pathColor, transparent: true, opacity: 0.6 }); //叠层的路径材质 this.buildHeight = 5; this.shopHeight = 30; //店铺高度 控制店铺相关的其它第三方组件高度 //服务icon 英文配置 this.iconEn = { "洗手间": "Toilets", "停车场": "Parking", "电梯": "Lift", "扶梯": "Escalator", "母婴室": "Baby care room", "服务台": "service desk" }; //添加平铺logo {floor:5, logoUrl:"./static/img/ss.png", imgW:395, imgH:376, xaxis:1550, yaxis:-860, site:30} this.logos = []; /** * 外立面 * Map_QM.util.initModelArr=[{url:"./static/model/jianfa.gltf",type:"out", scale:0.038, rot:{x:0,y:30,z:0}, site:{x:-20,y:-100,z:20}, colorModel:"gama" }]; */ this.initModelArr = []; // /** * 一直显示不隐藏, 在楼层内显示 */ this.modelArr = []; this.modelStr = [ //种树 { 'key': 'tree', 'url': 'static/img/model/tree.gltf', 'colorModel': 'line', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 1, 'y': 1, 'z': 1 } }, { 'key': 'tree2', 'url': 'static/img/model/tree2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'huatan1', 'url': 'static/img/model/huatan1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'huatan2', 'url': 'static/img/model/huatan2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'penquan2', 'url': 'static/img/model/penquan2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche1', 'url': 'static/img/model/qiche1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche2', 'url': 'static/img/model/qiche2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche3', 'url': 'static/img/model/qiche3.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche4', 'url': 'static/img/model/qiche4.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche5', 'url': 'static/img/model/qiche5.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche6', 'url': 'static/img/model/qiche6.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche7', 'url': 'static/img/model/qiche7.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche8', 'url': 'static/img/model/qiche8.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'qiche9', 'url': 'static/img/model/qiche9.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'chongdianzhuang', 'url': 'static/img/model/chongdianzhuang.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'IDS_H', 'url': 'static/img/model/IDS_H.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'IDS_V', 'url': 'static/img/model/IDS_V.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'xiaofangshuan', 'url': 'static/img/model/xiaofangshuan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'tingchechang', 'url': 'static/img/model/tingchechang.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'chechanglangan', 'url': 'static/img/model/chechanglangan.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'bangongyi', 'url': 'static/img/model/bangongyi.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'lvzhi', 'url': 'static/img/model/lvzhi.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'ren1', 'url': 'static/img/model/ren1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'ren2', 'url': 'static/img/model/ren2.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'ren3', 'url': 'static/img/model/ren3.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'ren4', 'url': 'static/img/model/ren4.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'ren5', 'url': 'static/img/model/ren5.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'ren6', 'url': 'static/img/model/ren6.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'yizi1', 'url': 'static/img/model/yizi1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } }, { 'key': 'gjz1', 'url': 'static/img/model/gjz1.glb', 'colorModel': 'gama', 'rot': { 'x': 1.5708, 'y': 0, 'z': 0 }, 'size': { 'x': 20, 'y': 20, 'z': 20 } } ]; this.fbxModels = []; //精灵模型 /** * 模型弹窗 * { htmlUrl: "
进入商场
", x: 55, y: 12, z: 3, click: true, type: "out" } */ this.tipArr = []; //模型标签 periphery /** * 室内地图标签 * Map_QM.util.labelIconArr([{floor:0,title:'肯德基
']) */ changeShowShopName: function (shopNums, elements) { if (shopNums.length === elements.length) { let labObj = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children; for (let i = 0; i < shopNums.length; i++) { for (let j = 0; j < labObj.length; j++) { if (labObj[j].name == shopNums[i]) { labObj[j].element.innerHTML = elements[i]; break; } } } } }, /** * @api {方法} unionShop() 店铺合并 * @apiGroup 地图显示 * @apiDescription 通过店铺编号合并店铺 合铺 * @apiVersion 2.0.0 * @apiParam {Array} shops 店铺编号数组 * @apiParam {Object} data 新的店铺数据(默认 空数据) * @apiSampleRequest off * * @apiParamExample {String} 请求示例 * Map_QM.unionShop(["L105","L106","L107","L108"],{name:"新店",shopNum:"L104-L108",color:"#F4A460"}) */ unionShop: function (shops, data = { name: "", shopNum: "shop", color: "#F4A460" }) { let shopObj = [], xAll = 0, yAll = 0; if (Array.isArray(shops) && shops.length > 1) { //删除店铺box let shopArea = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.children; for (let i = 0; i < shops.length; i++) { for (let k = 0; k < shopArea.length; k++) { if (shopArea[k].name == shops[i]) { xAll += shopArea[k].xaxis; yAll += shopArea[k].yaxis; shopObj.push(shopArea[k]); Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(shopArea[k]) break; } } } //删除文本标签 let labObj = Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.children; for (let i = 0; i < shops.length; i++) { for (let j = 0; j < labObj.length; j++) { if (labObj[j].name == shops[i]) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.remove(labObj[j]); break; } } } let point = { x: xAll / shopObj.length, y: yAll / shopObj.length }; let baseShop; for (let l = 0; l < shopObj.length; l++) { if (l == 0) { baseShop = new ThreeBSP(shopObj[0]); } else { baseShop = baseShop.union(new ThreeBSP(shopObj[l])); } } //ThreeBSP对象转化为网格模型对象 let mesh = baseShop.toMesh(); mesh.userData = data; mesh.userData.shopData = { formatColor: data.color }; mesh.userData.xaxis = point.x >> 0; mesh.userData.yaxis = point.y >> 0; mesh.userData.shopNum = data.name; mesh.userData.entColor = data.color; mesh.userData.type = "shop"; if (data.name) { mesh.name = data.name; let shopDiv = document.createElement('div'); shopDiv.style.cssText = css_LR; shopDiv.innerHTML = data.name; shopDiv.dataset.name = data.name; shopDiv.dataset.nameEn = data.nameEn || data.name; let shopLabel = new THREE.CSS2DObject(shopDiv); shopLabel.position.set(point.x >> 0, -1 * point.y >> 0, 30); shopLabel.name = data.shopNum || data.name; Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].labelObj.add(shopLabel); } mesh.material = new THREE.MeshPhongMaterial({ color: data.color || 0xF4A460, transparent: true, opacity: 0.9, side: THREE.DoubleSide, depthTest: true }); Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.add(mesh); } }, //////////////////////////////////////////////////////////////////////////////// /** * @param {Object} e * 地图BOX点击 */ onMouseClickBox: function (event) { if (Map_QM.util.isInnerTouch) { let mouse = new THREE.Vector2(); mouse.x = (event.offsetX / Map_QM.w) * 2 - 1; mouse.y = -(event.offsetY / Map_QM.h) * 2 + 1; Map_QM.onCallTouchORMouse(mouse); } }, onCallTouchORMouse: function (mouse) { if (!Map_QM.mapArr[Map_QM.util.selectBuild] && !Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor] || Map_QM.util.pathStateObj.isPathState) { return; } let raycaster = new THREE.Raycaster(); raycaster.setFromCamera(mouse, Map_QM.camera); let intersects = raycaster.intersectObjects(Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.children, true); let clickShop = false; //图标点击 for (let i = 0; i < intersects.length; i++) { //图标点击 if (intersects[i].object.userData && (intersects[i].object.userData.type == 'icon' || intersects[i].object.parent.userData.type == 'icon' || intersects[i].object.parent.parent.userData.type == 'icon')) { if (Map_QM.endModel && Map_QM.endModel.visible) { Map_QM.endModel.visible = false; } Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.clearPath(); let buildOrder = intersects[i].object.userData.buildOrder || intersects[i].object.parent.userData.buildOrder || intersects[i].object.parent.parent.userData.buildOrder || 0 let floorOrder = intersects[i].object.userData.floorOrder || intersects[i].object.parent.userData.floorOrder || intersects[i].object.parent.parent.userData.floorOrder || 0 let navCode = intersects[i].object.userData.navCode || intersects[i].object.parent.userData.navCode || intersects[i].object.parent.parent.userData.navCode let src = intersects[i].object.userData.src || intersects[i].object.parent.userData.src || intersects[i].object.parent.parent.userData.src let facCode = intersects[i].object.userData.facCode || intersects[i].object.parent.userData.facCode || intersects[i].object.parent.parent.userData.facCode let title = intersects[i].object.userData.title || intersects[i].object.parent.userData.title || intersects[i].object.parent.parent.userData.title /** * @api {事件} icon 点击设施图标 * @apiGroup 地图事件 * @apiDescription 用户点击设施图标后触发自定义事件 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("icon",onClickIcon,false); */ Map_QM.dispatchEvent({ type: 'icon', data: { "buildOrder": buildOrder, "floorOrder": floorOrder, "node": navCode, "src": src, "facCode": facCode, "title": title } }) console.log("触发 icon 事件 ", { type: 'icon', data: { "buildOrder": buildOrder, "floorOrder": floorOrder, "node": navCode, "src": src, "facCode": facCode, "title": title } }); return; } } for (let i = 0; i < intersects.length; i++) { //店铺BOX点击 if (intersects[i].object.userData && intersects[i].object.userData.type == "shop" && intersects[i].object.name != "") { if (Map_QM.endModel && Map_QM.endModel.visible) { Map_QM.endModel.visible = false; } clickShop = true; Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.clearPath(); Map_QM.setSelectShopMat(intersects[i].object); break; } } /** * @api {事件} shop 点击已绑定品牌的店铺 * @apiGroup 地图事件 * @apiDescription 用户点击店铺后触发自定义事件 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("shop",onClickShop,false); */ if (clickShop && Map_QM.selectShop && Map_QM.selectShop.userData) { if ((iot && Map_QM.selectShop.userData.shopData.hasOwnProperty("shopName")) || (!iot && Map_QM.selectShop.userData.shopData.hasOwnProperty("name"))) { Map_QM.dispatchEvent({ type: "shop", data: Map_QM.selectShop.userData }) } else { /** * @api {事件} onlyShop 点击未绑定品牌的店铺 * @apiGroup 地图事件 * @apiDescription 用户点击空店铺后触发自定义事件 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("onlyShop",onClickShop,false); */ Map_QM.dispatchEvent({ type: "onlyShop", data: Map_QM.selectShop.userData }) } } else { Map_QM.dispatchEvent({ type: "shop", data: null }) } }, /** * @api {方法} setSelectShopMatByName(shopNum) 设置box 选中 * @apiGroup 地图交互 * @apiDescription 地图box 选中 * @apiVersion 2.0.0 * @apiParam {String} shopNum POI编号 * * @apiSampleRequest off * * @apiParamExample {String} 请求示例 * * Map_QM.setSelectShopMatByName("L101"); * */ setSelectShopMatByName: function (ipName) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { let shopArr = Map_QM.mapArr[Map_QM.util.selectBuild][i].shopObj.children for (let k = 0; k < shopArr.length; k++) { if (shopArr[k].name == ipName) { Map_QM.setSelectShopMat(shopArr[k]) break } } } }, //改变选中店铺box setSelectShopMat: function (selObject) { TweenMax.killAll(true); if (Map_QM.selectShop) { Map_QM.selectShop.scale.z = 1; } Map_QM.parseSelectShop(selObject); }, /** * 初始化后调用 */ timeOutInit: function () { Map_QM.controls.update(); Map_QM.renderer.render(Map_QM.scene, Map_QM.camera); Map_QM.labelRenderer.render(Map_QM.scene, Map_QM.camera); if (Map_QM.callBackLoadOver) { let floorData = []; for (let i = 0; i < Map_QM.util.allMap.length; i++) { let build = []; for (let j = 0; j < Map_QM.util.allMap[i].buildArr.length; j++) { if (Map_QM.util.allMap[i].buildArr[j]) { build.push({ order: Map_QM.util.allMap[i].buildArr[j].order, name: Map_QM.util.allMap[i].buildArr[j].name }); } } floorData.push(build); } if (Map_QM.backObj) { Map_QM.controls.enabled = true; Map_QM.backObj.data = floorData; } Map_QM.callBackLoadOver(Map_QM.backObj); //初始化完成后回调 Map_QM.callBackLoadOver = null; Map_QM.backObj = null; } Map_QM.dispatchEvent({ type: "changeFloorOver", data: Map_QM.selectFloor }); Map_QM.collLabel(); }, autoChangeEleAngle: function () { if (Map_QM.mapArr[Map_QM.util.selectBuild]) { for (let m = 0; m < Map_QM.mapArr[Map_QM.util.selectBuild].length; m++) { if (Map_QM.mapArr[Map_QM.util.selectBuild][m].allObj.visible) { let svgChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].svgObj.children; let rat = Map_QM.controls.getRotateHorizontal(); svgChilds.forEach((item) => { if (Math.abs(item.rotation.x) < 0.5) { if ((rat - item.userData.rot) > 1.7 || (rat - item.userData.rot) < -1.7) { item.rotation.z = item.userData.rot < 0 ? item.userData.rot + 3.1415926 : item.userData.rot - 3.1415926; } else { item.rotation.z = item.userData.rot; } } }); let logoChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].shopObj.children; logoChilds.forEach((item) => { if (item.children.traverse) { item.children.traverse((obj) => { if (obj.userData.type == "logo") { if ((rat - obj.userData.rot) > 1.7 || (rat - obj.userData.rot) < -1.7) { obj.rotation.z = obj.userData.rot < 0 ? obj.userData.rot + 3.1415926 : obj.userData.rot - 3.1415926; } else { obj.rotation.z = obj.userData.rot; } } }) } }); } } } }, /** * 碰撞检测 * @param {Object} 传入检测楼层下标 */ controlsChock: function () { Map_QM.autoChangeEleAngle(); /** * @api {事件} MapAngleChange 地图的方向改变 * @apiGroup 地图事件 * @apiDescription 用户操作地图时触发 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("MapAngleChange",onMapAngleChange,false); */ Map_QM.dispatchEvent({ type: "MapAngleChange", data: { "hAngle": Map_QM.controls.getRotateHorizontal(), "vAngle": Map_QM.controls.getRotate() } }); if (Map_QM.util.options.inArea && isJUZ) { clearTimeout(shopTime); shopTime = setTimeout(() => { clearTimeout(shopTime); isJUZ = false; Map_QM.controls.reset() }, 3000); } if (debug) { Map_QM.util.guiOptions.cameraX = Map_QM.controls.object.position.x; Map_QM.util.guiOptions.cameraY = Map_QM.controls.object.position.y; Map_QM.util.guiOptions.cameraZ = Map_QM.controls.object.position.z; Map_QM.util.guiOptions.targatX = Map_QM.controls.target.x; Map_QM.util.guiOptions.targatY = Map_QM.controls.target.y; Map_QM.util.guiOptions.targatZ = Map_QM.controls.target.z; } if (Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) { //支持缩放切换 let distance = Map_QM.controls.getDistance(); if (distance <= Map_QM.util.changeDist.inner) { //切换到室内 Map_QM.util.isInnerTouch = true; if (Map_QM.outModelGap.visible) { TweenMax.to(Map_QM.outModelGap.scale, 0.5, { y: 0.01, ease: Quad.easeIn, onComplete: function () { Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面 } }); } if (Map_QM.peripheryGap.visible) { Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏周边 } if (!Map_QM.buildObj.userData.visible) { Map_QM.buildObj.visible = true; Map_QM.buildObj.userData.visible = true; Map_QM.changeFloorInner(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) } Map_QM.buildObj.traverse(obj => { if (obj.isMesh) { obj.material.opacity = obj.userData.opacity || 1; obj.material.transparent = true } }) } else if (distance > Map_QM.util.changeDist.outner && Map_QM.util.initModelArr.length > 1) { //周边 Map_QM.util.isInnerTouch = false; Map_QM.buildObj.userData.visible = false; Map_QM.buildObj.visible = false; Map_QM.changeFloorInner(Map_QM.util.deviceObj.build, Map_QM.util.deviceObj.floor) if (Map_QM.endModel && Map_QM.endModel.visible) { Map_QM.endModel.visible = false } if (!Map_QM.peripheryGap.visible) { TweenMax.to(Map_QM.peripheryGap.scale, 0.8, { y: 1 }); } Map_QM.hideObjecrGap(Map_QM.peripheryGap, true); if (Map_QM.outModelGap.visible) { TweenMax.to(Map_QM.outModelGap.scale, 0.5, { y: 0.01, ease: Quad.easeIn, onComplete: function () { Map_QM.hideObjecrGap(Map_QM.outModelGap, false); //隐藏外立面 } }); } } else { // 外立面 if (Map_QM.peripheryGap.visible) { TweenMax.to(Map_QM.peripheryGap.scale, 0.5, { y: 0.01, ease: Quad.easeIn, onComplete: function () { Map_QM.hideObjecrGap(Map_QM.peripheryGap, false); //隐藏 } }); } Map_QM.util.isInnerTouch = false; Map_QM.buildObj.userData.visible = false; Map_QM.buildObj.visible = true; if (Map_QM.endModel && Map_QM.endModel.visible) { Map_QM.endModel.visible = false } if (!Map_QM.outModelGap.visible) { TweenMax.to(Map_QM.outModelGap.scale, 0.8, { y: 1 }); } Map_QM.hideObjecrGap(Map_QM.outModelGap, true); } } Map_QM.collLabel(); }, hideObjecrGap: function (gap, isShow) { gap.visible = isShow gap.traverse(obj => { if (obj.userData && obj.userData.type == "2d_IP") { obj.element.style.visibility = isShow ? "visible" : "hidden" } if (obj.isMesh) { obj.material.opacity = obj.userData.opacity; obj.material.transparent = true } }) }, //内部碰撞检测 collLabel: function () { if (!Map_QM || !Map_QM.util.options.collision) { return; } Map_QM.util.timeObj.collTime = setTimeout(() => { clearTimeout(Map_QM.util.timeObj.collTime); let checkList = []; if (Map_QM.util.options.overlap) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.traverse((obj) => { if (obj.name == "floor" && Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.visible) { // checkList.push(obj); } }); } } if (Map_QM.mapArr[Map_QM.util.selectBuild]) { for (let m = 0; m < Map_QM.mapArr[Map_QM.util.selectBuild].length; m++) { if (Map_QM.mapArr[Map_QM.util.selectBuild][m].allObj.visible && (!Map_QM.buildObj.userData.hasOwnProperty("visible") || Map_QM.buildObj.userData.visible)) { let IconChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].iconLabel.children; IconChilds.forEach((item) => { item.element.style.visibility = "visible"; }); let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children; childs.forEach((item) => { item.element.style.visibility = "hidden"; }); let len = childs.length; for (let i = 0; i < len; i++) { let obj = childs[i].element if (obj.style.visibility == 'hidden' && obj.style.transform) { obj.style.visibility = 'visible' let labP = obj.style.transform.split('translate')[2].split(', ') for (let j = 0; j < i; j++) { if (childs[j].element.style.visibility == 'visible') { let pb = childs[j].element.style.transform.split('translate')[2].split(', ') let isCol = Map_QM.util.isCollision( new Map_QM.util.Point(labP[0].substring(1, labP[0].length - 2), labP[1].substring(0, labP[1].length - 3)), obj.clientWidth, obj.clientHeight, new Map_QM.util.Point(pb[0].substring(1, pb[0].length - 2), pb[1].substring(0, pb[1].length - 3)), childs[j].element.clientWidth, childs[j].element.clientHeight ) if (isCol) { obj.style.visibility = 'hidden' break; } } } } } let iLen = IconChilds.length; for (let ii = 0; ii < iLen; ii++) { let objIcon = IconChilds[ii].element; if (objIcon.style.visibility == "visible" && objIcon.style.transform) { let labPIcon = objIcon.style.transform.split("translate")[2].split(", "); for (let jj = ii + 1; jj < iLen; jj++) { let pbe = IconChilds[jj].element.style.transform.split("translate")[2].split(", "); let isCol2 = Map_QM.util.isCollision(new Map_QM.util.Point(labPIcon[0].substring(1, labPIcon[0].length - 2), labPIcon[1].substring(0, labPIcon[1].length - 3)), objIcon.clientWidth, objIcon.clientHeight, new Map_QM.util.Point(pbe[0].substring(1, pbe[0].length - 2), pbe[1].substring(0, pbe[1].length - 3)), IconChilds[jj].element .clientWidth, IconChilds[jj].element.clientHeight); if (isCol2) { IconChilds[jj].element.style.visibility = "hidden"; } } } } if (Map_QM.util.options.overlap) { let renChild = Map_QM.mapArr[Map_QM.util.selectBuild][m].showTagObj.children; const { left, top } = Map_QM.renderer.domElement.getBoundingClientRect(); renChild.forEach((item) => { if (item.element.style.visibility == "visible") { let check = Map_QM.util.blocked(item.element, checkList, m, top, left); if (check) { item.element.style.visibility = "hidden"; } } }); childs.forEach((item) => { if (item.element.style.visibility == "visible") { let check = Map_QM.util.blocked(item.element, checkList, m, top, left); if (check) { item.element.style.visibility = "hidden"; } } }); IconChilds.forEach((item) => { if (item.element.style.visibility == "visible") { let check = Map_QM.util.blocked(item.element, checkList, m, top, left); if (check) { item.element.style.visibility = "hidden"; } } }); } } else { let IconChilds = Map_QM.mapArr[Map_QM.util.selectBuild][m].iconLabel.children; IconChilds.forEach((item) => { item.element.style.visibility = "hidden"; }); let childs = Map_QM.mapArr[Map_QM.util.selectBuild][m].labelObj.children; childs.forEach((item) => { item.element.style.visibility = "hidden"; }); } } } }, 500); }, /** * 寻路---------------------------------------------------------------------------------------------------------------------------------------- */ /** * @api {方法} bounceIcon({type:"xsj"}) 图标弹跳 * @apiGroup 地图导航 * @apiDescription 地图图标弹跳效果 * @apiVersion 2.0.0 * @apiParam {String} iconType 设施缩写 * * @apiSampleRequest off * * @apiParamExample {String} 请求示例 * * Map_QM.bounceIcon({type:"xsj"}); * */ bounceIcon: function (iconType) { let toFloor = parseInt(Map_QM.util.selectFloor); let facs = Map_QM.mapArr[Map_QM.util.selectBuild][toFloor].serObj.children; //交通图标 for (let i = 0; i < facs.length; i++) { if (facs[i].type == "Sprite") { facs[i].reSetSite(); if (facs[i].facCode == iconType) { facs[i].jumpIcon(); } } } }, /** * @api {方法} pathIcon({type:"xsj"}) 获取最近设施 * @apiGroup 地图导航 * @apiDescription 获取离当前楼层最近的设施 * @apiVersion 2.0.0 * @apiParam {JSON} type 设施缩写 * * @apiSampleRequest off * * @apiParamExample {String} 请求示例 * * Map_QM.pathIcon({type:"xsj"}); * * @apiSuccessExample 返回示例 * { * "floor": 楼层编号, "node": 设施导航点,"typeCode":设施编号 * } * */ pathIcon: function (iconType) { let selIcon; // let minS = -1; toIcon = iconType.type; if (!Map_QM.util.startObj.build && parseInt(Map_QM.util.startObj.build) != 0) { Map_QM.util.startObj.build = parseInt(Map_QM.util.deviceObj.build); } let startNade = Map_QM.util.startObj.build + "_" + Map_QM.util.startObj.floor + "_" + Map_QM.util.startObj.node; const costAll = dijkstra.single_source_shortest_paths(Map_QM.util.pathStateObj.graphPath, startNade, startNade).costs; if (costAll) { for (let i = 0; i < Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)].length; i++) { let sers = Map_QM.mapArr[parseInt(Map_QM.util.deviceObj.build)][i].serObj.children; //服务图标 for (let n = 0; n < sers.length; n++) { if (sers[n].facCode == iconType.type) { let toNade = parseInt(Map_QM.util.deviceObj.build) + "_" + sers[n].floor + "_" + sers[n].navCode; if (!selIcon) { minS = costAll[toNade]; if (minS) { selIcon = sers[n]; } } else { let s1 = costAll[toNade]; if (s1 && s1 < minS) { minS = s1; selIcon = sers[n]; } } } } } if (selIcon) { return { "build": parseInt(Map_QM.util.deviceObj.build), "floor": selIcon.floor, site: { x: selIcon.position.x, y: selIcon.position.y }, "node": selIcon.navCode, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; } else { // 当前楼栋没有 for (let b = 0; b < Map_QM.mapArr.length; b++) { if (b != parseInt(Map_QM.util.deviceObj.build)) { for (let i = 0; i < Map_QM.mapArr[b].length; i++) { let sers = Map_QM.mapArr[b][i].serObj.children; //服务图标 for (let n = 0; n < sers.length; n++) { if (sers[n].facCode == iconType.type) { let toNade = parseInt(Map_QM.util.deviceObj.build) + "_" + sers[n].floor + "_" + sers[n].navCode; if (!selIcon) { minS = costAll[toNade]; if (minS) { selIcon = sers[n]; } } else { let s1 = costAll[toNade]; if (s1 && s1 < minS) { minS = s1; selIcon = sers[n]; } } } } } } } } if (selIcon) { return { "build": parseInt(Map_QM.util.deviceObj.build), "floor": selIcon.floor, "node": selIcon.navCode, site: { x: selIcon.position.x, y: selIcon.position.y }, "no": selIcon.no, "typeCode": Map_QM.util.getFacType(iconType.type) }; } } }, /** * @api {方法} pathByStartAndOver(startObj,toObj,callBackFun) 地图路径规划 * @apiGroup 地图导航 * @apiDescription 根据传入的起、终点;直接导航 * @apiVersion 2.0.0 * @apiParam {String} startObj.shopNum 店铺编号/车位编号 * @apiParam {String} startObj.type "shop"/"park" * * @apiParam {String} toObj.shopNum 店铺编号/车位编号 * @apiParam {String} toObj.type "shop"/"park" * * @apiParam {Function} callBackFun 回调函数 * * @apiSampleRequest off * * @apiParamExample {String} 请求示例 * * Map_QM.pathByStartAndOver({"shopNum":"L102","type":"shop"},{"shopNum":"L204","type":"shop"}); * */ pathByStartAndOver: function (startObj, toObj, callBackFun) { try { Map_QM.util.startObj = this.shopNumToNavPoint(startObj, startObj.type); let overObj = this.shopNumToNavPoint(toObj, toObj.type); this.pathNode(overObj, callBackFun); } catch (e) { return "传入点位无法导航"; } }, /** * @api {方法} changeStartPoint() 设置起始点位 * @apiGroup 地图导航 * @apiDescription 设置起始点位 * @apiVersion 2.0.0 * @apiParam {int} build 起点楼栋编号 * @apiParam {int} floor 起点楼层编号 * @apiParam {String} node 起点编号 * @apiParam {int} angle 起点角度 * * @apiSampleRequest off * * @apiParamExample {String} 请求示例 * * Map_QM.changeStartPoint({"build":0, "floor":3, "node":"20", "angle":0}); * */ changeStartPoint: function (toObj) { this.clearFloor(); for (let i = 0; i < this.mapArr[parseInt(this.util.startObj.build)].length; i++) { for (let len = this.mapArr[parseInt(this.util.startObj.build)][i].allObj.children.length - 1; len >= 0; len--) { let obj = this.mapArr[parseInt(this.util.startObj.build)][i].allObj.children[len] if (obj.userData.type == "start") { this.mapArr[parseInt(this.util.startObj.build)][i].allObj.remove(obj) } } } if (toObj && toObj.node) { let pathData = this.util.allMap[parseInt(toObj.build)].buildArr[parseInt(toObj.floor)].mapData.path this.util.deviceObj.xaxis = this.util.startObj.xaxis = pathData.nodes[parseInt(toObj.node)].x this.util.deviceObj.yaxis = this.util.startObj.yaxis = pathData.nodes[parseInt(toObj.node)].y this.util.deviceObj.build = this.util.startObj.build = parseInt(toObj.build); this.util.deviceObj.floor = this.util.startObj.floor = parseInt(toObj.floor); this.util.deviceObj.node = this.util.startObj.node = toObj.node; this.util.deviceObj.angle = this.util.startObj.angle = toObj.angle || 0; } else { let pathData = this.util.allMap[parseInt(this.util.deviceObj.build)].buildArr[parseInt(this.util.deviceObj.floor)].mapData.path pathData.nodes.sort(this.util.sortNode); this.util.deviceObj.xaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].x this.util.deviceObj.yaxis = pathData.nodes[parseInt(this.util.deviceObj.node)].y this.util.startObj = this.util.deviceObj } this.mapArr[parseInt(this.util.startObj.build)][parseInt(this.util.startObj.floor)].setStartSite( this.util.startObj.xaxis, this.util.startObj.yaxis, parseInt(this.util.shopHeight) ) }, /** * @api {方法} changeMapIPState(ipName,color) 改变POI颜色 * @apiGroup 地图交互 * @apiDescription 改变POI 颜色 * @apiVersion 2.0.0 * @apiParam {string} ipName POI名称 * @apiParam {string} color 颜色字符串 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.changeMapIPState("L1001","#ffff00"); * */ changeMapIPState: function (ipName, color) { // #775544 #AD8164 for (let i = 0; i < this.mapArr[this.util.selectBuild].length; i++) { let shopArr = this.mapArr[this.util.selectBuild][i].shopObj.children; for (let k = 0; k < shopArr.length; k++) { if (shopArr[k].name == ipName) { shopArr[k].material = this.util.getMeshMaterial(color || 0xeab16e); break; } } } }, /** * @api {方法} getMapIPData(ipName) 获取POI 基础数据 * @apiGroup 地图交互 * @apiDescription 获取POI 基础数据 * @apiVersion 2.0.0 * @apiParam {string} ipName POI名称 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.getMapIPData("L1001"); * * @apiSuccessExample 返回示例 * { * shopNum:店铺编号, shopName:店铺名 node:导航点, floor:楼层编号, xaxis:中心点X坐标, yaxis:中心点Y坐标, borderColor:边框色, entColor:填充色 * } */ getMapIPData: function (ipName) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { let shopArr = Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.children; for (let k = 0; k < shopArr.length; k++) { if (shopArr[k].name == ipName) { return shopArr[k].userData; } } } }, /** * @api {方法} pathNode() 地图模拟导航 * @apiGroup 地图导航 * @apiDescription 地图路径模拟导航 * @apiVersion 2.0.0 * @apiParam {int} floor 楼层编号 * @apiParam {string} node 路径点位编号 * @apiParam {function} callBackFun 回调方法 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.pathNode({build:0, floor:2,node:"53"},callBackFun); * */ pathNode: function (toObj, callBackFun) { if (!toObj) { return { direction: "", wayList: [] } } pathCameraState = Map_QM.util.options.pathStyle; Map_QM.onShowDeviceSite() Map_QM.clearFloor(-1, true); Map_QM.selectShop = null; Map_QM.util.pathStateObj.isPathState = true; if (Map_QM.util.initModelArr && Map_QM.util.initModelArr.length > 0 && Map_QM.util.changeDist.inner > Map_QM.util.options.minDis) { Map_QM.controls.maxDistance = Map_QM.util.changeDist.inner; } if (!Map_QM.util.startObj.xaxis && !Map_QM.util.startObj.yaxis) { Map_QM.changeStartPoint(null); } Map_QM.util.overObj = null; Map_QM.util.overObj = { build: toObj.build || 0, floor: toObj.floor, node: toObj.node, shopNum: toObj.shopNum }; if (Map_QM.util.overObj.node != "") { Map_QM.cancelRender(); this.onFindPathModel(); if (Map_QM.util.options.overlap) { //叠层导航--固定地图仰角 Map_QM.controls.maxPolarAngle = 1.17; Map_QM.controls.minPolarAngle = 1.17; } if (callBackFun) { Map_QM.parseForShopArr(); const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr)); callBackFun(data); } Map_QM.startRender(); } }, parseForShopArr: function () { Map_QM.util.pathStateObj.forShopArr = { direction: "", wayList: [] } Map_QM.forShopArr.forEach((item, index) => { if (item.hasOwnProperty("Direction")) { Map_QM.util.pathStateObj.forShopArr.direction = item.Direction; Map_QM.util.pathStateObj.forShopArr.directionEn = item.DirectionEn; } if (item.hasOwnProperty("wayShop") && item.wayShop) { for (let i = 0; i < item.wayShop.length; i++) { let enTlite = item.wayShop[i].shop.nameEn == "" ? item.wayShop[i].shop.name : item.wayShop[i].shop.nameEn; Map_QM.util.pathStateObj.forShopArr.wayList.push({ isAddPrefix: false, name: "经过 " + item.wayShop[i].shop.name, nameEn: "PASS " + enTlite, logoPath: item.wayShop[i].shop.logoPath, code: item.wayShop[i].shop.code, shopNum: iot ? item.wayShop[i].shop.houseNumber : item.wayShop[i].shop.houseNum }); } } if (item.hasOwnProperty("Facilities") && item.Facilities) { //设施 Map_QM.util.pathStateObj.forShopArr.wayList.push({ isAddPrefix: true, name: "乘坐 " + item.Facilities.userData.title + "到 " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, nameEn: "BY " + item.Facilities.userData.title + "TO " + Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[index + 1].floor)].floorName, logoPath: item.Facilities.imgUrl, code: (((Math.random()) * 0x1234567) | 0).toString(16).substring(0), shopNum: item.Facilities.userData.facCode + item.Facilities.userData.no }); } }); }, /** * @api {方法} getGapByPathNode() 获取实际距离 * @apiGroup 地图导航 * @apiDescription 通过点位获取距离 * @apiVersion 2.0.0 * @apiParam {int} floor 楼层编号 * @apiParam {string} node 路径点位编号 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.getGapByPathNode({floor:2,node:"53"}); * * @apiSuccessExample {Object} dist 距离米数 time 步行时间 * { * dis:200,time:4 * } */ getGapByPathNode: function (toObj) { let startNade = Map_QM.util.deviceObj.build + "_" + Map_QM.util.deviceObj.floor + "_" + Map_QM.util.deviceObj.node; let toNade = toObj.build + "_" + toObj.floor + "_" + toObj.node; let path = { "cost": -1 }, minTime = 1; try { path = dijkstra.find_path(Map_QM.util.pathStateObj.graphPath, startNade, toNade); minTime = parseInt(path.cost / Map_QM.util.options.mapScale / 50) < 0.5 ? 0.5 : parseInt(path.cost / Map_QM.util.options.mapScale / 50); console.log(`距离目的地 ${parseInt(path.cost / Map_QM.util.options.mapScale)} 米,预计${mint} 分钟`); // 21 是比例尺 } catch (e) { console.log(e) } return { dis: parseInt(path.cost / Map_QM.util.options.mapScale), time: minTime } }, /** * @api {方法} getAllIcon() 获取所有Icon * @apiGroup 地图数据 * @apiDescription 获取所有Icon * @apiVersion 2.0.0 * @apiParam {int} floorOrder 楼层编号(默认 所有) * * @apiSampleRequest off * */ getAllIcon: function (floorOrder = -1, buildOrder = -1) { let icons = []; if (floorOrder != -1) { let bd = buildOrder == -1 ? Map_QM.util.selectBuild : buildOrder; let sers = Map_QM.mapArr[bd][floorOrder].serObj.children; //服务图标 for (let n = 0; n < sers.length; n++) { if (sers[n].type == "Sprite") { let title = sers[n].userData.title; let titleEn = Map_QM.util.iconEn[title]; let type = sers[n].facCode; let imgUrl = sers[n].imgUrl; if (sers[n].facCode == "upft" || sers[n].facCode == "downft" || sers[n].facCode == "ft") { if (title == "上扶梯" || title == "下扶梯") { title = "扶梯"; } titleEn = Map_QM.util.iconEn["扶梯"]; type = "ft"; } let icon = { type: type, floor: floorOrder, imgUrl: imgUrl, poid: sers[n].userData.poid, title: title, titleEn: titleEn }; icons.push(icon); } } return icons; } for (let j = 0; j < Map_QM.mapArr.length; j++) { let iconBuild = []; for (let i = 0; i < Map_QM.mapArr[j].length; i++) { let iconArr = []; if (Map_QM.mapArr[j][i].serObj) { let sers = Map_QM.mapArr[j][i].serObj.children; //服务图标 for (let n = 0; n < sers.length; n++) { if (sers[n].type == "Sprite") { let title = sers[n].userData.title; let titleEn = Map_QM.util.iconEn[title]; let type = sers[n].facCode; let imgUrl = sers[n].imgUrl; if (sers[n].facCode == "upft" || sers[n].facCode == "downft" || sers[n].facCode == "ft") { title = "扶梯"; titleEn = Map_QM.util.iconEn[title]; type = "ft"; imgUrl = Map_QM.util.beforPath + "static/img/ft.png"; } let icon = { type: type, floor: i, imgUrl: imgUrl, poid: sers[n].userData.poid, title: title, titleEn: titleEn }; iconArr.push(icon); } } } iconBuild.push(iconArr); } icons.push(iconBuild); } return icons; }, /** * @api {方法} pathPark() 获取车位点位 * @apiGroup 地图数据 * @apiDescription 获取车位导航点 * @apiVersion 2.0.0 * @apiParam {String} shopNum 车位编号 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.pathPark({shopNum:"B1002"}); * * @apiSuccessExample 返回示例 * { * shopNum: 车位编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标 * } */ pathPark: function (toObj) { return this.shopNumToNavPoint(toObj, "park"); }, /** * @api {方法} pathShopByName() 获取店铺点位 * @apiGroup 地图数据 * @apiDescription 通过店铺名称获取点位 * @apiVersion 2.0.0 * @apiParam {String} shopName 店铺名称 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.pathShopByName("金拱门"); * * @apiSuccessExample 返回示例 * { * shopNum: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点 * } */ pathShopByName: function (shopName) { for (let item of Map_QM.util.shopData) { if (item.name === shopName) { let toObj = { "shopNum": iot ? item.houseNumber : item.houseNum, "node": item.yaxis }; for (let h = 0; h < Map_QM.util.allMap.length; h++) { let sArr = Map_QM.util.allMap[h].buildArr; for (let i = 0; i < sArr.length; i++) { let shops = Map_QM.util.allMap[h].buildArr[i].mapData.shopArea; for (let k = 0; k < shops.length; k++) { if (shops[k].name == toObj.shopNum) { toObj.floor = i; toObj.build = h; toObj.node = shops[k].shopNav; toObj.xaxis = shops[k].xaxis; toObj.yaxis = shops[k].yaxis; if (shops[k].comeIn) { toObj.comeIn = shops[k].comeIn; } return toObj; } } } } return toObj; } } }, /** * @api {方法} shopNumToNavPoint() 获取导航点位 * @apiGroup 地图导航 * @apiDescription 通过店铺编号或车位获取导航点位 * @apiVersion 2.0.0 * @apiParam {Object} object build,floor,shopNum 楼栋编号,楼层编号,店铺或车位编号 * @apiParam {String} type 店铺或车位标识 "shop" "park" * * @apiSampleRequest off * * @apiSuccessExample 返回示例 * { * shopNum: 店铺编号, node: 导航点, floor: 楼层编号, xaxis: 中心点X坐标, yaxis: 中心点Y坐标, comeIn:店铺多门点 * } */ shopNumToNavPoint: function (obj, type) { let shopArr; let reObj = { build: Map_QM.util.selectBuild, node: "", xaxis: "", yaxis: "", floor: "", comeIn: "" }; for (let h = 0; h < Map_QM.util.allMap.length; h++) { let sArr = Map_QM.util.allMap[h].buildArr; for (let i = 0; i < sArr.length; i++) { if (type == "shop") { shopArr = sArr[i].mapData.shopArea; } else if (type == "park") { shopArr = sArr[i].mapData.parkArea; } for (let k = 0; k < shopArr.length; k++) { if (shopArr[k].name == obj.shopNum) { reObj.floor = i; reObj.build = h; reObj.xaxis = shopArr[k].xaxis; reObj.yaxis = shopArr[k].yaxis; reObj.node = shopArr[k].shopNav; reObj.shopNum = obj.shopNum; if (shopArr[k].comeIn) { reObj.comeIn = shopArr[k].comeIn; } return reObj; } } } } }, /** * 模拟导航获取路线 */ onFindPathModel: function (usePath = null) { Map_QM.forShopArr.length = 0; Map_QM.util._indexPathFloor = 0; Map_QM.util.pathStateObj.isPathPlay = true; if (parseInt(Map_QM.util.startObj.node) == -1) { return; } if (!Map_QM.util.startObj.xaxis) { let pathData = Map_QM.util.allMap[parseInt(Map_QM.util.startObj.build)].buildArr[parseInt(Map_QM.util.startObj.floor)].mapData.path; Map_QM.util.startObj.xaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].x; Map_QM.util.startObj.yaxis = pathData.nodes[parseInt(Map_QM.util.startObj.node)].y; } if (!usePath) { usePath = Map_QM.util.pathStateObj.graphPath; } Map_QM.forShopPath(usePath); }, forShopPath: function (usePath) { let startNade = Map_QM.util.startObj.build + "_" + Map_QM.util.startObj.floor + "_" + Map_QM.util.startObj.node; let toNade = Map_QM.util.overObj.build + "_" + Map_QM.util.overObj.floor + "_" + Map_QM.util.overObj.node; let path; try { path = dijkstra.find_path(usePath, startNade, toNade); } catch (e) { console.log(e); return; } let PathPoint = path.nodes; let Dir = "向前出发", index = 0; let DirEn = "to forward"; this.forShopArr = []; if (PathPoint.length > 1) { this.forShopArr.push({ build: Map_QM.util.startObj.build, floor: Map_QM.util.startObj.floor, PathPoint: [] }); let pathData; for (let j = 0; j < PathPoint.length; j++) { let array = PathPoint[j].split("_"); pathData = Map_QM.util.allMap[parseInt(array[0])].buildArr[parseInt(array[1])].mapData.path; if (array[0] == this.forShopArr[index].build) { if (array[1] == this.forShopArr[index].floor) { this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]); } else { if (j > 0) { this.forShopArr[index].Facilities = this.getFacilIcon(PathPoint[j - 1].split("_"), parseInt(array[0])); } else { this.forShopArr[index].Facilities = null; } this.forShopArr.push({ build: parseInt(array[0]), floor: parseInt(array[1]), PathPoint: [] }); index++; this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]); } } else { this.forShopArr.push({ build: parseInt(array[0]), floor: parseInt(array[1]), PathPoint: [] }); index++; this.forShopArr[index].PathPoint.push(pathData.nodes[parseInt(array[2])]); } } let dy = 0, dx = 0, ang = 0; if (this.forShopArr[0].PathPoint.length > 1) { if (this.forShopArr[0].PathPoint.length == 2) { dy = this.forShopArr[0].PathPoint[1].y - this.forShopArr[0].PathPoint[0].y; dx = this.forShopArr[0].PathPoint[1].x - this.forShopArr[0].PathPoint[0].x; } else { dy = this.forShopArr[0].PathPoint[2].y - this.forShopArr[0].PathPoint[1].y; dx = this.forShopArr[0].PathPoint[2].x - this.forShopArr[0].PathPoint[1].x; } ang = Math.atan2(dy, dx) * 180 / Math.PI - Map_QM.util.deviceObj.angle; ang = ang > 180 ? ang - 360 : ang; ang = ang < -180 ? ang + 360 : ang; if (ang < -50 && ang >= -130) { Dir = "向前出发"; DirEn = "to forward"; } else if (ang >= -50 && ang < 50) { Dir = "向右出发"; DirEn = "to right"; } else if (ang >= 50 && ang < 130) { Dir = "向后出发"; DirEn = "to back"; } else { Dir = "向左出发"; DirEn = "to left"; } } let pLen = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint.length; Map_QM.util.overObj.xaxis = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint[pLen - 1].x; Map_QM.util.overObj.yaxis = Map_QM.forShopArr[Map_QM.forShopArr.length - 1].PathPoint[pLen - 1].y if (Map_QM.forShopArr.length > 0) { // "floor" PathPoint Direction (Facilities) Map_QM.forShopArr[0].Direction = Dir; Map_QM.forShopArr[0].DirectionEn = DirEn; for (let m = 0; m < Map_QM.forShopArr.length; m++) { //查找经过店铺 Map_QM.forShopArr[m].wayShop = Map_QM.foreignShop(Map_QM.forShopArr[m].PathPoint, Map_QM.forShopArr[m].build, Map_QM.forShopArr[m].floor, m); if (Map_QM.util.overObj.build == Map_QM.forShopArr[m].build && Map_QM.util.overObj.floor == Map_QM.forShopArr[m].floor) { let len = Map_QM.forShopArr[m].wayShop.length; if (Map_QM.forShopArr[m].wayShop[len - 1] && Map_QM.forShopArr[m].wayShop[len - 1].shop.yaxis == Map_QM.util.overObj.node) { Map_QM.forShopArr[m].wayShop.pop(); } } } /** * @api {事件} InitPathOver 地图导航状态完成 * @apiGroup 地图事件 * @apiDescription 地图开始导航时触发 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("InitPathOver",onInitPathOver,false); */ Map_QM.dispatchEvent({ type: 'InitPathOver', data: Map_QM.forShopArr }); } else { console.error('无可行路径,请检查起、终点位'); return; } this.onFindPathToObj(); } }, /** * 途径店铺 */ foreignShop: function (pathArr, build, cFloor, m) { let shopList = []; let shops = Map_QM.mapArr[parseInt(build)][parseInt(cFloor)].allObj.children; for (let n = 0; n < pathArr.length; n++) { for (let i = 0; i < shops.length; i++) { if (shops[i].userData && shops[i].userData.type == "shop" && shops[i].userData.navRecommend) { if (shops[i].userData.node == pathArr[n].id && shops[i].userData.shopData) { let data = { pathArrIn: m, pathIndex: n, shop: shops[i].userData.shopData }; shopList.push(data); break; } } } } return shopList; }, getFacilIcon: function (fromFArr, build = -1) { if (build === -1) { build = Map_QM.util.selectBuild } let childs = this.mapArr[build][fromFArr[1]].serObj.children; let selectEle for (let i = 0; i < childs.length; i++) { if (childs[i].navCode == fromFArr[2]) { selectEle = { imgUrl: childs[i].imgUrl, userData: childs[i].userData, position: { x: childs[i].position.x, y: childs[i].position.y } } break } } return selectEle }, /** * 寻路动画方法 */ onFindPathToObj: function () { outTime = -1; Map_QM.util._indexPathFloor = 0; Map_QM.callBackLoadOver = Map_QM.callBackForPathShop; //楼层初始化完成后回调 if (Map_QM.util.options.overlap) { if (Map_QM.forShopArr.length == 2) { Map_QM.changeFloorInner(-1, Map_QM.forShopArr[0].floor, () => { }, Map_QM.forShopArr[1].floor); } else if (Map_QM.forShopArr.length == 3) { Map_QM.changeFloorInner(-1, Map_QM.forShopArr[0].floor, () => { }, Map_QM.forShopArr[1].floor, Map_QM.forShopArr[2].floor); } else { Map_QM.changeFloorInner(-1, Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor); } } else { if (pathCameraState == "2D") { Map_QM.onShowMeDir(); Map_QM.controls.enabled = false; Map_QM.guide = Map_QM.man_2d; } Map_QM.changeBuildInner(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build, Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor); } }, /** * 播放楼层动画完成后 */ callBackForPathShop: function () { Map_QM.callBackLoadOver = null; if (Map_QM.util.pathStateObj.isPathState) { //如果是寻路状态,继续导航 Map_QM.onFindPath(); } }, /** * 寻路方法 * @param {Object} startN * @param {Object} endN */ onFindPath: function () { TweenMax.killAll(true); if (Map_QM.util.options.overlap) { Map_QM.mapArr[Map_QM.util.overObj.build][Map_QM.util.overObj.floor].setOverSite(Map_QM.util.overObj.xaxis, Map_QM.util.overObj.yaxis, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.overObj.floor].allObj.position.y + parseInt(Map_QM.util.shopHeight)); } else { if (Map_QM.util.overObj.floor == Map_QM.util.selectFloor && Map_QM.util.overObj.xaxis) { Map_QM.mapArr[Map_QM.util.overObj.build][Map_QM.util.overObj.floor].setOverSite(Map_QM.util.overObj.xaxis, Map_QM.util.overObj.yaxis, parseInt(Map_QM.util.shopHeight)); } } if (Map_QM.forShopArr.length > 0) { document.addEventListener("pathOver", Map_QM.onFindPathFloor, true); if (Map_QM.util.options.overlap && Map_QM.util._indexPathFloor == 0) {//叠层 for (let pathObj of Map_QM.forShopArr) { Map_QM.mapArr[pathObj.build][pathObj.floor].findPath.onFindPathAnimation(pathObj.PathPoint, pathObj.floor); //传入数组 } let extrudeSettings; let vects = new THREE.CurvePath(); let vects2 = new THREE.CurvePath(); if (Map_QM.forShopArr.length == 2) { vects.add(new THREE.LineCurve3(new THREE.Vector3(Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].x, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[0].floor].allObj.position.y, Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].y), new THREE.Vector3(Map_QM.forShopArr[1].PathPoint[0].x, Map_QM.mapArr[Map_QM.forShopArr[1].build][Map_QM.forShopArr[1].floor].allObj.position.y, Map_QM.forShopArr[1].PathPoint[0].y))); extrudeSettings = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects }; let geometry = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings); let lineDashed = new THREE.Mesh(geometry, Map_QM.util.tubeMaterial); Map_QM.dtLineGroup.add(lineDashed); } if (Map_QM.forShopArr.length == 3) { vects.add(new THREE.LineCurve3(new THREE.Vector3(Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].x, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[0].floor].allObj.position.y, Map_QM.forShopArr[0].PathPoint[Map_QM.forShopArr[0].PathPoint.length - 1].y), new THREE.Vector3(Map_QM.forShopArr[1].PathPoint[0].x, Map_QM.mapArr[Map_QM.forShopArr[1].build][Map_QM.forShopArr[1].floor].allObj.position.y, Map_QM.forShopArr[1].PathPoint[0].y))); vects2.add(new THREE.LineCurve3(new THREE.Vector3(Map_QM.forShopArr[1].PathPoint[Map_QM.forShopArr[1].PathPoint.length - 1].x, Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.forShopArr[1].floor].allObj.position.y, Map_QM.forShopArr[1].PathPoint[Map_QM.forShopArr[1].PathPoint.length - 1].y), new THREE.Vector3(Map_QM.forShopArr[2].PathPoint[0].x, Map_QM.mapArr[Map_QM.forShopArr[2].build][Map_QM.forShopArr[2].floor].allObj.position.y, Map_QM.forShopArr[2].PathPoint[0].y))); extrudeSettings = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects }; extrudeSettings2 = { bevelEnabled: true, steps: 200, bevelSegments: 8, extrudePath: vects2 }; let geometry = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings); let lineDashed = new THREE.Mesh(geometry, Map_QM.util.tubeMaterial); Map_QM.dtLineGroup.add(lineDashed); let geometry2 = new THREE.ExtrudeGeometry(Map_QM.shape, extrudeSettings2); let lineDashed2 = new THREE.Mesh(geometry2, Map_QM.util.tubeMaterial); Map_QM.dtLineGroup.add(lineDashed2); } } else { Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.clearPath(); Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.onFindPathAnimation(Map_QM.forShopArr[Map_QM.util._indexPathFloor].PathPoint); //传入数组 } Map_QM.mapArr[Map_QM.forShopArr[Map_QM.util._indexPathFloor].build][Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor].findPath.guidePathPlay(Map_QM.forShopArr[Map_QM.util._indexPathFloor]); Map_QM.controlsChock(); } }, /** * 显示楼层 */ showNavFloor: function (fromFloor, toFloor, build) { let floorArr = []; let min = Math.min(fromFloor, toFloor); let max = Math.max(fromFloor, toFloor); for (let i = min; i <= max; i++) { floorArr.push(Map_QM.mapArr[build][i].floorName); } if (floorArr.length > 5) { floorArr.splice(2, floorArr.length - 3); floorArr[1] = "..."; } return floorArr; }, //导航完成事件 onFindPathFloor: function (event) { document.removeEventListener("pathOver", Map_QM.onFindPathFloor); if (Map_QM.forShopArr.length <= Map_QM.util._indexPathFloor) { return; } if (Map_QM.util._indexPathFloor < Map_QM.forShopArr.length - 1) { //楼层切换 if (Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities) { let pathFloor = Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor; let x0 = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.position.x + 64; let y0 = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.position.y; let model = Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.model; /** * @api {事件} PathPlaying 地图导航的实时状态 * @apiGroup 地图事件 * @apiDescription 地图导航过程中实时触发 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("PathPlaying",onPathPlaying,false); */ Map_QM.dispatchEvent({ //寻路中返回小人当前所在点位 type: 'PathPlaying', data: { "shopNum": Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.facCode + Map_QM.forShopArr[Map_QM.util._indexPathFloor].Facilities.userData.no } }); let box; if (model && model.userData.name == "dt") { model.traverse(function (child) { if (child.isMesh && child.name == "zhitibox") { box = child; } if (child.isMesh && (child.name == 'zhitijiegou' || child.name == 'zhitiboli')) { child.scale.y = 7.5; } }); } let zo = 2, tz = 2, boxT = 0, boxZ = 0; let add = Map_QM.util.options.showStyle ? 80 : 40; Map_QM.util._indexPathFloor++; let toFloor = parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor); Map_QM.util.selectFloor = toFloor; let floorArr = Map_QM.showNavFloor(pathFloor, toFloor, parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)); //电梯旁显示的楼层名称 if (pathFloor < toFloor) { tz = (floorArr.length - 1) * add; boxT = 27 } else { zo = (floorArr.length - 1) * add; boxZ = 27 } document.getElementById('moveFloor').style.bottom = zo + "px"; document.getElementById('moveFloor').style.width = add + "px"; document.getElementById('moveFloor').style.height = add + "px"; Map_QM.moveFloorbg.element.style.visibility = "visible"; Map_QM.moveFloorbg.element.style.width = (add + 8) + "px"; Map_QM.moveFloorbg.element.style.height = (floorArr.length * add) + "px"; Map_QM.moveFloorbg.position.set(x0, y0, 80); Map_QM.moveFloorbg.applyMatrix4(Map_QM.mapArr[parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build)][pathFloor].allObj.matrix); Map_QM.moveFloorbg.applyMatrix4(Map_QM.sceneGap.matrix); let floorBox = document.getElementById('floorBox'); while (floorBox.hasChildNodes()) { floorBox.removeChild(floorBox.firstChild); } for (let i = floorArr.length - 1; i >= 0; i--) { let span2 = document.createElement('span') span2.style.cssText = 'display: block;color: #000000; text-align: center;' span2.style.fontSize = '16px' if (Map_QM.util.options.showStyle) { span2.style.fontSize = '32px' } span2.style.width = add + 'px' span2.style.height = add + 'px' span2.style.lineHeight = add + 'px' span2.innerText = floorArr[i] floorBox.appendChild(span2) } TweenMax.fromTo('#moveFloor', 1.5, { bottom: zo }, { bottom: tz, delay: 0.1, onComplete: function () { Map_QM.moveFloorbg.element.style.visibility = "hidden"; if (!Map_QM.util.options.overlap) { Map_QM.callBackLoadOver = Map_QM.callBackForPathShop; //楼层初始化完成后回调 Map_QM.changeFloorInner(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build, Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor); } else { if (Map_QM.forShopArr > Map_QM.util._indexPathFloor) { Map_QM.util.selectFloor = Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor; } Map_QM.clearFloor(-1, false); Map_QM.callBackForPathShop(); } } }); if (box) { TweenMax.fromTo( box.position, 1.2, { y: boxZ }, { y: boxT, delay: 0.2, onComplete: function () { box.position.y = 0 model.traverse(function (child) { if (child.isMesh && (child.name == 'zhitijiegou' || child.name == 'zhitiboli')) { child.scale.y = 1; } }) } } ) } if (pathCameraState == "3D") { let xt = Map_QM.guide.position.x + event.detail.dx * 10; let yt = Map_QM.guide.position.y + event.detail.dy * 10; if (model && model.userData.name == "upft") { Map_QM.guide.visible = true; TweenMax.to(Map_QM.guide.position, 1.3, { x: xt, y: yt, z: 50, onComplete: function () { Map_QM.guide.visible = false; } }); } if (model && model.userData.name == "downft") { Map_QM.guide.visible = true; TweenMax.to(Map_QM.guide.position, 1.3, { x: xt, y: yt, z: -50, onComplete: function () { Map_QM.guide.visible = false; } }); } } } else { //楼栋切换 Map_QM.util._indexPathFloor++; Map_QM.callBackLoadOver = Map_QM.callBackForPathShop; Map_QM.changeBuildInner(Map_QM.forShopArr[Map_QM.util._indexPathFloor].build, Map_QM.forShopArr[Map_QM.util._indexPathFloor].floor); } } else { Map_QM.util.startObj = Map_QM.util.deviceObj; /** * @api {事件} PathPlayOver 地图导航完成 * @apiGroup 地图事件 * @apiDescription 地图导航到达目标点时触发 * @apiVersion 2.0.0 * @apiSampleRequest off * * @apiParamExample 请求示例 * Map_QM.addEventListener("PathPlayOver",onPathPlayOver,false); */ Map_QM.dispatchEvent({ //寻路完成 type: 'PathPlayOver', data: "PathPlayOver" }); } }, /** * 楼层状态清理 */ clearFloor: function (fIndex = -1, reSet = true) { isJUZ = false; if (fIndex == -1) { fIndex = Map_QM.util.deviceObj.floor; } if (Map_QM.selectShop) { Map_QM.selectShop.scale.z = 1; } if (Map_QM.endModel && Map_QM.endModel.visible) { Map_QM.endModel.visible = false; } if (Map_QM.endIcon && Map_QM.endIcon.visible) { Map_QM.endIcon.visible = false; } if (Map_QM.moveFloorbg) { Map_QM.moveFloorbg.element.style.visibility = "hidden"; } if (reSet) { //叠层不处理 if (Map_QM.mapArr[Map_QM.util.selectBuild] && Map_QM.mapArr[Map_QM.util.selectBuild].length > 0) { for (let i = 0; i < Map_QM.mapArr[Map_QM.util.selectBuild].length; i++) { let lines = Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj; for (let j = lines.children.length - 1; j >= 0; j--) { Map_QM.mapArr[Map_QM.util.selectBuild][i].lineObj.remove(lines.children[j]); } let child = Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj; for (let k = child.children.length - 1; k >= 0; k--) { if (child.children[k].name == "lineDash") { Map_QM.mapArr[Map_QM.util.selectBuild][i].allObj.remove(child.children[k]); } } Map_QM.mapArr[Map_QM.util.selectBuild][i].findPath.clearPath(); } } Map_QM.remove_child(Map_QM.dtLineGroup); } TweenMax.killAll(true); }, remove_child: function (remObj) { if (!remObj) { return; } let child_elem = remObj.children; for (let i = child_elem.length - 1; i >= 0; i--) { if (child_elem[i].children.length > 0) { Map_QM.remove_child(child_elem[i]); } else { if (child_elem[i] instanceof THREE.Mesh) { child_elem[i].geometry.dispose(); // 删除几何体 if (child_elem[i].material !== undefined) Map_QM.removeMaterial(child_elem.material); // 删除材质 } } if (child_elem[i].name != "light" && child_elem[i].name != "dtline") { remObj.remove(child_elem[i]); } } }, removeMaterial: function (material) { if (Array.isArray(material)) { for (var i = 0, l = material.length; i < l; i++) { this.removeMaterialFromRefCounter(material[i]); } } else { this.removeMaterialFromRefCounter(material); } }, removeMaterialFromRefCounter: function (material) { var materialsRefCounter = this.materialsRefCounter; if (materialsRefCounter) { var count = materialsRefCounter.get(material); count--; if (count === 0) { materialsRefCounter.delete(material); delete this.materials[material.uuid]; } else { materialsRefCounter.set(material, count); } } }, /** * @api {方法} pathStop() 导航暂停/播放 * @apiGroup 地图导航 * @apiDescription 导航动画暂停/播放 * @apiVersion 2.0.0 * * @apiSampleRequest off * */ pathStop: function (isPlaying) { Map_QM.util.pathStateObj.isPathPlay = isPlaying === undefined ? !Map_QM.util.pathStateObj.isPathPlay : isPlaying; Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].findPath.pathPlay.isPlay = Map_QM.util.pathStateObj.isPathPlay; }, /** * @api {方法} pathRePlay() 导航动画重播 * @apiGroup 地图导航 * @apiDescription 导航动画重播 * @apiVersion 2.0.0 * * @apiSampleRequest off * */ pathRePlay: function () { clearTimeout(Map_QM.util.timeObj.pathTime); Map_QM.util.timeObj.pathTime = setTimeout(() => { clearTimeout(Map_QM.util.timeObj.pathTime); if (Map_QM.util.overObj && Map_QM.forShopArr[0]) { Map_QM.util.pathStateObj.isPathPlay = true; Map_QM.clearFloor(); Map_QM.onFindPathToObj(); } }, 100); }, /** * @api {方法} ChangePathByFt() 切换扶梯模式 * @apiGroup 地图导航 * @apiDescription 导航切换扶梯模式 * @apiVersion 2.0.0 * * @apiParam {function} callBack 回调函数 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.ChangePathByFt(function); * */ ChangePathByFt: function (callBack) { clearTimeout(Map_QM.util.timeObj.pathTime); Map_QM.util.timeObj.pathTime = setTimeout(() => { clearTimeout(Map_QM.util.timeObj.pathTime); if (Map_QM.util.overObj) { Map_QM.clearFloor(); Map_QM.onFindPathModel(Map_QM.util.pathStateObj.ftPath); if (callBack) { Map_QM.parseForShopArr(); const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr)) callBack(data); } } }, 100); }, /** * @api {方法} ChangePathByDt() 切换电梯模式 * @apiGroup 地图导航 * @apiDescription 导航切换电梯模式 * @apiVersion 2.0.0 * * @apiParam {function} callBack 回调函数 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.ChangePathByDt(function); * */ ChangePathByDt: function (callBack) { clearTimeout(Map_QM.util.timeObj.pathTime); Map_QM.util.timeObj.pathTime = setTimeout(() => { clearTimeout(Map_QM.util.timeObj.pathTime); if (Map_QM.util.overObj) { Map_QM.clearFloor(); Map_QM.onFindPathModel(Map_QM.util.pathStateObj.dtPath); if (callBack) { Map_QM.parseForShopArr(); const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr)) callBack(data); } } }, 100); }, /** * @api {方法} ChangePathByGood() 切换最佳模式 * @apiGroup 地图导航 * @apiDescription 导航切换最佳模式 * @apiVersion 2.0.0 * * @apiParam {function} callBack 回调函数 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.ChangePathByGood(function); * */ ChangePathByGood: function (callBack) { clearTimeout(Map_QM.util.timeObj.pathTime); Map_QM.util.timeObj.pathTime = setTimeout(() => { clearTimeout(Map_QM.util.timeObj.pathTime); if (Map_QM.util.overObj) { Map_QM.clearFloor(); Map_QM.onFindPathModel(Map_QM.util.pathStateObj.graphPath); if (callBack) { Map_QM.parseForShopArr(); const data = JSON.parse(JSON.stringify(Map_QM.util.pathStateObj.forShopArr)) callBack(data); } } }, 100); }, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// changeDocmentResize: function (e) { let ele = document.getElementById(options.containerId || "mapContainer"); let w = parseInt(ele.clientWidth) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('width')) let h = parseInt(ele.clientHeight) || parseInt(window.getComputedStyle(ele, null).getPropertyValue('height')) Map_QM.changeWindowResize(w, h); }, /** * @api {方法} changeWindowResize() 窗口变化 * @apiGroup 地图交互 * @apiDescription 窗口变化 * @apiVersion 2.0.0 * * @apiParam {int} width 窗口宽 * @apiParam {int} height 窗口高 * * @apiSampleRequest off * * @apiParamExample 请求示例 * * Map_QM.changeWindowResize(1280,1080); */ changeWindowResize: function (width, height) { Map_QM.aspect = width / height; Map_QM.cameraPerspective.aspect = Map_QM.aspect; Map_QM.cameraPerspective.updateProjectionMatrix(); Map_QM.cameraOrtho.left = 340 * Map_QM.aspect / -2; Map_QM.cameraOrtho.right = 340 * Map_QM.aspect / 2; Map_QM.cameraOrtho.top = 340 / 2; Map_QM.cameraOrtho.bottom = 340 / -2; Map_QM.cameraOrtho.updateProjectionMatrix(); Map_QM.renderer.setSize(width, height); Map_QM.labelRenderer.setSize(width, height); Map_QM.w = width; Map_QM.h = height; } } /** * @api {方法} init(callBack,options) 地图初始化 * @apiGroup 地图数据 * @apiDescription 初始化地图赋值 Map_QM * @apiVersion 2.0.0 * * @apiParam {function} callBack 初始化成功后的回调函数 * @apiParam {object} options 初始化对象 * @apiParam {int} options.build 设备所在楼栋编号 默认值6 * @apiParam {int} options.floor 设备所在楼层编号 默认值 true * @apiParam {int} options.navPoint 设备导航点 默认值 -1 * @apiParam {int} options.angle 起点设备角度 默认值 0 * @apiParam {string} options.perc_H 弹窗的偏移量 默认值 "-50%"; * @apiParam {string} options.containerId 地图div容器Id 默认值 "mapContainer" * @apiParam {string} options.playSpeed 动画播放速度 默认值6 * @apiParam {boolean} options.collision 是否支持名称的碰撞检测 默认值 true * @apiParam {boolean} options.showStyle 是否4K显示 默认值false * @apiParam {boolean} options.modelIcon 交通设施是否使用模型 默认值 true * @apiParam {Array} options.otherPath 人为干预的路线 默认值 []; * @apiParam {int} options.fSpace 双叠层状态下楼层的间距 默认值 500 * @apiParam {uint} options.navColor 途径店铺颜色 默认值 0xEE6A50 * @apiParam {boolean} options.overlap 是否叠层 默认值 false * @apiParam {boolean} options.shadow 是否显示阴影 默认值 true * @apiParam {boolean} options.iconName 图标名称是否显示 默认值false * @apiParam {uint} options.pathColor 导航路径颜色 默认值 0xb47834, * @apiParam {string} options.pathStyle 导航第一视角 默认值 "2D", * @apiParam {string} options.shopStyle 店铺显示字段编号(shopNum)名称(shopName) 默认值 "shopName", * @apiParam {int} options.camZoom 地图显示我的方向状态的放大倍数 默认值 3 * @apiParam {boolean} options.inArea 地图点击后是否聚焦到当前位置 默认值 false * @apiParam {Array} options.iconUrl 设施库图标 默认值 [] * * @apiSampleRequest off * @apiParamExample {String} 请求示例 * * MainMap_QM.init(callBackLoadOver,{build : 0, floor : 3, navPoint : 7, angle : 0, perc_H : "-50%",containerId : "mapContainer"}); */ MainMap_QM.init = function (callBack, options) { Map_QM = new MainMap_QM(callBack, options); return Map_QM; } Object.assign(MainMap_QM.prototype, THREE.EventDispatcher.prototype); //////////////////////////////////////-------------------------------FloorMap FloorMap_QM = function (bIndex, fIndex, floorName) { this.Model_QM = new MyModel_QM(); this.facUtil = new Facilities_QM(); this.findPath = new FindPath_QM(); this.logoUtil = new ShopLogo_QM(); this.allObj = new THREE.Group(); this.allObj.name = floorName; this.allObj.rotation.x = Math.PI / -2; this.labelObj = new THREE.Group(); this.labelObj.renderOrder = 100; this.iconLabel = new THREE.Group(); this.iconLabel.renderOrder = 100; this.floorOrder = fIndex; this.buildOrder = bIndex this.floorName = floorName; //存放设施图标 this.serObj = new THREE.Object3D(); //存放车位box this.parkObj = new THREE.Group(); //标签 this.tagObj = new THREE.Group(); this.tagObj.renderOrder = 100; this.devObj = new THREE.Group(); //存放设施图标 this.svgObj = new THREE.Group(); //店铺 this.shopObj = new THREE.Group(); this.allObj.add(this.shopObj); this.allObj.add(this.svgObj); this.allObj.add(this.serObj); this.allObj.add(this.devObj); this.allObj.add(this.labelObj); this.allObj.add(this.iconLabel); this.allObj.add(this.tagObj); //标签 this.showTagObj = new THREE.Group(); this.showTagObj.renderOrder = 100; this.allObj.add(this.showTagObj); //线条 this.lineObj = new THREE.Group(); this.lineObj.renderOrder = 100; this.allObj.add(this.lineObj); this.startIcon; } FloorMap_QM.prototype = { initDraw: function () { this.initFloor(); this.initFacilitie(); this.initStairs(); this.initTextArea(); this.initWall(); this.initDecos(); this.initPark(); this.initModel(); this.initTree(); //植树 this.initLogos(); //贴图 }, initLogos: function () { let sopce = this; if (Map_QM.util.logos) { Map_QM.util.logos.map((item) => { if (item.build == sopce.buildOrder && item.floor == sopce.floorOrder) { sopce.logoUtil.renderIcon(item, sopce, item.site || 0); } }); } }, initModel: function () { let sopce = this; if (Map_QM.util.modelArr) { for (let i = 0; i < Map_QM.util.modelArr.length; i++) { if (Map_QM.util.modelArr[i].floor == this.floorOrder) { new THREE.GLTFLoader().load(Map_QM.util.beforPath + Map_QM.util.modelArr[i].url, function (object) {//加载路径fbx文件 let mod = object.scene; mod.traverse(function (child) { if (child.isMesh) { child.receiveShadow = Map_QM.util.options.shadow; child.castShadow = Map_QM.util.options.shadow; child.userData.opacity = child.material.opacity; if (child.material.map) { child.material.map.encoding = THREE.LinearEncoding; //贴图需要转换成 线性编码 } child.material.color.convertGammaToLinear(0.7); } }); for (let t = 0; t < Map_QM.util.modelArr[i].list.length; t++) { let obj = mod.clone(); obj.position.set(Map_QM.util.modelArr[i].list[t].site.x, -1 * Map_QM.util.modelArr[i].list[t].site.y, Map_QM.util.modelArr[i].list[t].site.z); obj.scale.set(Map_QM.util.modelArr[i].list[t].size.x, Map_QM.util.modelArr[i].list[t].size.y, Map_QM.util.modelArr[i].list[t].size.z); obj.rotateX(Map_QM.util.modelArr[i].list[t].rot.x); obj.rotateY(Map_QM.util.modelArr[i].list[t].rot.y); obj.rotateZ(Map_QM.util.modelArr[i].list[t].rot.z); sopce.allObj.add(obj); } showTagObj }); } } } if (Map_QM.util.labelIconArr) { for (let i = 0; i < Map_QM.util.labelIconArr.length; i++) { if (Map_QM.util.labelIconArr[i].floor == this.floorOrder) { let SpriteDiv = document.createElement('div'); SpriteDiv.className = Map_QM.util.labelIconArr[i].className; SpriteDiv.innerHTML = Map_QM.util.labelIconArr[i].title; SpriteDiv.dataset.id = Map_QM.util.labelIconArr[i].data.id; SpriteDiv.dataset.x = Map_QM.util.labelIconArr[i].site.x; SpriteDiv.dataset.y = Map_QM.util.labelIconArr[i].site.y; SpriteDiv.dataset.z = Map_QM.util.labelIconArr[i].site.z; let pointLabel = new THREE.CSS2DObject(SpriteDiv); pointLabel.position.set(Map_QM.util.labelIconArr[i].site.x, -1 * Map_QM.util.labelIconArr[i].site.y, Map_QM.util.labelIconArr[i].site.z); pointLabel.name = Map_QM.util.labelIconArr[i].title; pointLabel.userData = Map_QM.util.labelIconArr[i].data; pointLabel.userData.site = Map_QM.util.labelIconArr[i].site; if (Map_QM.util.labelIconArr[i].click) { //可点击 SpriteDiv.addEventListener("click", (event) => { Map_QM.dispatchEvent({ type: 'labelIcon', data: event.target.dataset }); }, false); } else { pointLabel.element.style.pointerEvents = "none"; } pointLabel.userData.floor = Map_QM.util.labelIconArr[i].floor; sopce.showTagObj.add(pointLabel); } } } }, initTree: function () { let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData; if (mapData.models) { for (let t = 0; t < mapData.models.length; t++) { for (let i = 0; i < Map_QM.util.fbxModels.length; i++) { if (mapData.models[t].type == Map_QM.util.fbxModels[i].key) { let obj = Map_QM.util.fbxModels[i].obj.clone(); obj.position.set(mapData.models[t].x, -1 * mapData.models[t].y, mapData.models[t].site); obj.scale.set(mapData.models[t].scale, mapData.models[t].scale, mapData.models[t].scale); obj.rotateX(Map_QM.util.fbxModels[i].operation.rot.x); obj.rotateY(-1 * mapData.models[t].angle * Math.PI / 180); this.allObj.add(obj); } } } } }, //初始化单楼层 initFloor: function () { let floor; let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData; let entColor, borderColor; if (mapData.floorArea) { floor = Map_QM.util.changeAreaToString(mapData.floorArea); } let bLen = mapData.buildArea.length; let hLen = mapData.hollowArea.length; let hows_f = []; for (let m = 0; m < hLen; m++) { hows_f.push(Map_QM.util.changeAreaToString(mapData.hollowArea[m])); } if (floor) { entColor = parseInt(mapData.floorArea.entColor.replace("#", "0x"), 16); borderColor = parseInt(mapData.floorArea.borderColor.replace("#", "0x"), 16); floorH = parseInt(mapData.floorArea.toHeight); let mash = this.Model_QM.MyModelShape(floor, hows_f, mapData.floorArea, entColor, borderColor, 10); mash.receiveShadow = true; mash.castShadow = false; mash.userData = { "type": "floor", "order": this.floorOrder }; mash.userData.opacity = mapData.floorArea.alphaModle / 100 || 0; mash.name = "floor"; this.allObj.add(mash); } /////////////////////初始化楼栋 for (let i = 0; i < bLen; i++) { let build = Map_QM.util.changeAreaToString(mapData.buildArea[i]); let hows = []; for (let t = 0; t < hLen; t++) { let isIn = Map_QM.util.checkAreaInArea(mapData.hollowArea[t], mapData.buildArea[i]); if (isIn) { hows.push(Map_QM.util.changeAreaToString(mapData.hollowArea[t])); } } entColor = parseInt(mapData.buildArea[i].entColor.replace("#", "0x"), 16); borderColor = parseInt(mapData.buildArea[i].borderColor.replace("#", "0x"), 16); Map_QM.util.buildHeight = Math.max(parseInt(mapData.buildArea[i].toHeight), Map_QM.util.buildHeight); buildH = parseInt(mapData.buildArea[i].toHeight); let mash = this.Model_QM.MyModelShape(build, hows, mapData.buildArea[i], entColor, borderColor, 30); mash.receiveShadow = true; mash.castShadow = false; mash.userData = { "type": "build", "order": this.floorOrder }; mash.userData.opacity = mapData.buildArea[i].alphaModle / 100 || 0; mash.name = "floor"; this.allObj.add(mash); } //店铺 let sLen = mapData.shopArea.length; let show = (showE = ""); let showLeb = ""; let logo = "", navRecommend = false, shopD = {}, type = "deco"; let shopData = Map_QM.util.shopData; for (let i = 0; i < sLen; i++) { if (Map_QM.util.changeAreaToString(mapData.shopArea[i]) != "") { let arr = Map_QM.util.changeShopLinesToString(mapData.shopArea[i]); entColor = mapData.shopArea[i].entColor || "#b79266"; borderColor = mapData.shopArea[i].borderColor || "#b79266"; show = (showE = mapData.shopArea[i].name); logo = ""; showLeb = ""; navRecommend = false; shopD = {}; if (shopData) { for (let h = 0; h < shopData.length; h++) { let houseNum = iot ? shopData[h].houseNumber : shopData[h].houseNum; if (typeof (shopData[h].buildingOrder) == "undefined") { if (shopData[h].floorOrder == this.floorOrder) { if (houseNum == mapData.shopArea[i].name) { show = iot ? shopData[h].shopName : shopData[h].name; showLeb = houseNum; showE = iot ? shopData[h].shopNameEn : shopData[h].nameEn; logo = shopData[h].logoPath; if (shopData[h].navRecommend == undefined) { navRecommend = true; } else { navRecommend = shopData[h].navRecommend; } shopD = shopData[h]; if (shopData[h].isNewStore) { //新店 mapData.shopArea[i].type = "new-shop"; this.addTagLabel(mapData.shopArea[i], { "node": mapData.shopArea[i].shopNav, "floor": this.floorOrder, "build": this.buildOrder }); } if ((shopData[h].shopActList && shopData[h].shopActList.length > 0)) { //促销 mapData.shopArea[i].type = "promotion"; this.addTagLabel(mapData.shopArea[i], { "node": mapData.shopArea[i].shopNav, "floor": this.floorOrder, "build": this.buildOrder }); } if (shopData[h].formatColor) { entColor = parseInt(shopData[h].formatColor.replace("#", "0x"), 16); } else { entColor = "#eab16e"; } if (shopData[h].borderColor) { borderColor = parseInt(shopData[h].borderColor.replace("#", "0x"), 16); } else { borderColor = "#eab16e"; } break; } } } else { if (shopData[h].buildingOrder == this.buildOrder && shopData[h].floorOrder == this.floorOrder) { if (houseNum == mapData.shopArea[i].name) { show = iot ? shopData[h].shopName : shopData[h].name; showLeb = houseNum; showE = iot ? shopData[h].shopNameEn : shopData[h].nameEn; logo = shopData[h].logoPath; if (shopData[h].navRecommend == undefined) { navRecommend = true; } else { navRecommend = shopData[h].navRecommend; } shopD = shopData[h]; if (shopData[h].isNewStore) { //新店 mapData.shopArea[i].type = "new-shop"; this.addTagLabel(mapData.shopArea[i], { "node": mapData.shopArea[i].shopNav, "floor": this.floorOrder, "build": this.buildOrder }); } if ((shopData[h].shopActList && shopData[h].shopActList.length > 0)) { //促销 mapData.shopArea[i].type = "promotion"; this.addTagLabel(mapData.shopArea[i], { "node": mapData.shopArea[i].shopNav, "floor": this.floorOrder, "build": this.buildOrder }); } if (shopData[h].formatColor) { entColor = parseInt(shopData[h].formatColor.replace("#", "0x"), 16); } else { entColor = "#eab16e"; } if (shopData[h].borderColor) { borderColor = parseInt(shopData[h].borderColor.replace("#", "0x"), 16); } else { borderColor = "#eab16e"; } break; } } } } } let hollShop = []; if (mapData.shopArea[i].hollArea) { for (let k = 0; k < mapData.shopArea[i].hollArea.length; k++) { hollShop.push(Map_QM.util.changeAreaToString(mapData.shopArea[i].hollArea[k])); } } let mahc = this.Model_QM.MyModelShape(arr, hollShop, mapData.shopArea[i], entColor, borderColor, 100); mahc.node = mapData.shopArea[i].shopNav; mahc.userData = { "shopData": shopD, "xaxis": mapData.shopArea[i].xaxis >> 0, "yaxis": mapData.shopArea[i].yaxis >> 0, "node": mahc.node, "floor": this.floorOrder, "build": this.buildOrder, "navRecommend": navRecommend, "type": "shop", "entColor": entColor, "shopNum": mapData.shopArea[i].name, "shopName": show, "logo": logo, "borderColor": borderColor }; mahc.userData.opacity = mapData.shopArea[i].alphaModle / 100 || 0; mahc.name = showLeb; mahc.xaxis = mapData.shopArea[i].xaxis >> 0; mahc.yaxis = mapData.shopArea[i].yaxis >> 0; this.shopObj.add(mahc); if (mapData.shopArea[i].logoUrl && mapData.shopArea[i].isLabel == 0) { //添加logo this.logoUtil.renderIcon(mapData.shopArea[i], mahc, parseInt(mapData.shopArea[i].toHeight) + parseInt(mapData.shopArea[i].site || 0) + 1); } else { //添加文字 let some = Map_QM.util.options.boxShop.some((item) => { return mapData.shopArea[i].name.includes(item); }); if (showLeb != "" || some) { showLeb = mapData.shopArea[i].name; let shopDiv = document.createElement('div'); shopDiv.style.cssText = css_LR; shopDiv.innerHTML = Map_QM.util.options.shopStyle == "shopName" ? show : mapData.shopArea[i].name; shopDiv.dataset.name = show; shopDiv.dataset.nameEn = showE; shopDiv.style.visibility = "hidden"; let shopLabel = new THREE.CSS2DObject(shopDiv); shopLabel.position.set(mapData.shopArea[i].xaxis >> 0, -1 * mapData.shopArea[i].yaxis >> 0, parseInt(mapData.shopArea[i].toHeight) + parseInt(mapData.shopArea[i].site || 0)); shopLabel.name = mapData.shopArea[i].name; this.labelObj.add(shopLabel); } } } } }, addTagLabel: function (obj, userData) { let shopDiv = document.createElement('img'); shopDiv.src = Map_QM.util.beforPath + "static/img/" + obj.type + ".png"; shopDiv.style.zIndex = 200; shopDiv.style.width = "3.125vw"; let shopLabel = new THREE.CSS2DObject(shopDiv); shopLabel.userData = userData; shopLabel.position.set(obj.xaxis >> 0, -1 * obj.yaxis >> 0, Map_QM.util.shopHeight); this.tagObj.add(shopLabel); }, //初始化服务图标 initFacilitie: function () { let serArr = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData.icons; for (let i = 0; i < serArr.length; i++) { if (serArr[i].hasOwnProperty("iShow")) { if (serArr[i].iShow) { serArr[i].floorOrder = this.floorOrder; serArr[i].buildOrder = this.buildOrder; this.facUtil.renderIcon(serArr[i], this); } } else { serArr[i].floorOrder = this.floorOrder; serArr[i].buildOrder = this.buildOrder; this.facUtil.renderIcon(serArr[i], this); } } }, //初始化电梯图标 initStairs: function () { let facArr = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData.stairs; for (let i = 0; i < facArr.length; i++) { if (facArr[i].facCode == "ft") { if (Map_QM.util.pathStateObj.elevatorDown && Map_QM.util.pathStateObj.elevator) { if (facArr[i].downState) { //上扶梯 let ex = Map_QM.util.pathStateObj.elevator.clone(); ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0); ex.rotation.y = (facArr[i].angle || 0) * Math.PI / -180; ex.userData.type = "icon"; ex.userData.use = "3d"; ex.userData.name = "upft"; ex.userData.buildOrder = facArr[i].buildOrder ex.userData.floorOrder = facArr[i].floorOrder ex.userData.navCode = facArr[i].navCode ex.userData.src = "static/img/ft.png"; ex.userData.facCode = facArr[i].facCode ex.userData.title = facArr[i].title this.serObj.add(ex); facArr[i].facCode = "ft"; this.facUtil.renderIcon(facArr[i], this, false, ex); } else if (facArr[i].upState) { //下扶梯 let ex = Map_QM.util.pathStateObj.elevatorDown.clone(); ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0); ex.rotation.y = (facArr[i].angle || 0) * Math.PI / -180; ex.userData.type = "icon"; ex.userData.use = "3d"; ex.userData.name = "downft"; ex.userData.buildOrder = facArr[i].buildOrder ex.userData.floorOrder = facArr[i].floorOrder ex.userData.navCode = facArr[i].navCode ex.userData.src = "static/img/ft.png"; ex.userData.facCode = facArr[i].facCode ex.userData.title = facArr[i].title this.serObj.add(ex); facArr[i].facCode = "ft"; this.facUtil.renderIcon(facArr[i], this, false, ex); } else { this.facUtil.renderIcon(facArr[i], this, true); } } else { this.facUtil.renderIcon(facArr[i], this, true); } } else if (facArr[i].facCode == "upft") { if (Map_QM.util.pathStateObj.elevator) { let ex = Map_QM.util.pathStateObj.elevator.clone(); ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0); ex.rotation.y = (facArr[i].angle || 0) * Math.PI / -180; ex.userData.type = "icon"; ex.userData.use = "3d"; ex.userData.name = "upft"; ex.userData.buildOrder = facArr[i].buildOrder ex.userData.floorOrder = facArr[i].floorOrder ex.userData.navCode = facArr[i].navCode ex.userData.src = "static/img/ft.png"; ex.userData.facCode = facArr[i].facCode ex.userData.title = facArr[i].title this.serObj.add(ex); facArr[i].facCode = "ft"; this.facUtil.renderIcon(facArr[i], this, false, ex); } else { facArr[i].facCode = "ft"; this.facUtil.renderIcon(facArr[i], this, true); } } else if (facArr[i].facCode == "downft") { if (Map_QM.util.pathStateObj.elevatorDown) { let ex = Map_QM.util.pathStateObj.elevatorDown.clone(); ex.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0); ex.rotation.y = (facArr[i].angle || 0) * Math.PI / -180; ex.userData.type = "icon"; ex.userData.use = "3d"; ex.userData.name = "downft"; ex.userData.buildOrder = facArr[i].buildOrder ex.userData.floorOrder = facArr[i].floorOrder ex.userData.navCode = facArr[i].navCode ex.userData.src = "static/img/ft.png"; ex.userData.facCode = facArr[i].facCode ex.userData.title = facArr[i].title this.serObj.add(ex); facArr[i].facCode = "ft"; this.facUtil.renderIcon(facArr[i], this, false, ex); } else { facArr[i].facCode = "ft"; this.facUtil.renderIcon(facArr[i], this, true); } } else if (facArr[i].facCode == "dt") { if (Map_QM.util.pathStateObj.straight) { let stra = Map_QM.util.pathStateObj.straight.clone(); stra.position.set(facArr[i].x, -1 * facArr[i].y, facArr[i].site || 0); stra.rotation.y = (facArr[i].angle || 0) * Math.PI / -180; stra.userData.type = "icon"; stra.userData.use = "3d"; stra.userData.name = "dt"; stra.userData.buildOrder = facArr[i].buildOrder stra.userData.floorOrder = facArr[i].floorOrder stra.userData.navCode = facArr[i].navCode stra.userData.src = "static/img/dt.png"; stra.userData.facCode = facArr[i].facCode stra.userData.title = facArr[i].title this.serObj.add(stra); this.facUtil.renderIcon(facArr[i], this, false, stra); } else { this.facUtil.renderIcon(facArr[i], this, true); } } else { this.facUtil.renderIcon(facArr[i], this, true); } } }, //初始化装饰图标 initDecos: function () { let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData; let sLen = mapData.decos.length; let entColor, borderColor; if (mapData.groupArea) { for (let k = 0; k < mapData.groupArea.length; k++) { var gp = new THREE.Group(); gp.rotateX(mapData.groupArea[k].angleX * Math.PI / 180); gp.rotateY(mapData.groupArea[k].angleY * Math.PI / 180); gp.rotateZ(mapData.groupArea[k].angleZ * Math.PI / 180); for (let i = 0; i < sLen; i++) { if (mapData.decos[i].gid && mapData.decos[i].gid == mapData.groupArea[k]._name && Map_QM.util.changeAreaToString(mapData.decos[i]) != "") { let arr = Map_QM.util.changeAreaToString(mapData.decos[i]); entColor = parseInt(mapData.decos[i].entColor.replace("#", "0x"), 16); borderColor = parseInt(mapData.decos[i].borderColor.replace("#", "0x"), 16); let show = mapData.decos[i].name == "deco" ? "" : mapData.decos[i].name; let hollShop = []; if (mapData.decos[i].hollArea) { for (let k = 0; k < mapData.decos[i].hollArea.length; k++) { hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k])); } } let mahc = this.Model_QM.MyModelShape(arr, hollShop, mapData.decos[i], entColor, borderColor, 240); mahc.xaxis = mapData.decos[i].xaxis >> 0; mahc.yaxis = mapData.decos[i].yaxis >> 0; mahc.node = mapData.decos[i].shopNav; mahc.userData = { "type": "deco", "name": show }; mahc.userData.opacity = mapData.decos[i].alphaModle / 100 || 0; gp.add(mahc); mahc.position.x = -1 * mapData.groupArea[k].xaxis; mahc.position.y = mapData.groupArea[k].yaxis; } } this.allObj.add(gp); gp.position.x = mapData.groupArea[k].xaxis; gp.position.y = -1 * mapData.groupArea[k].yaxis; gp.position.z = mapData.groupArea[k].site || 0; gp.scale.set(mapData.groupArea[k].scale, mapData.groupArea[k].scale, mapData.groupArea[k].scale); } } for (let i = 0; i < sLen; i++) { if ((!mapData.decos[i].gid || mapData.decos[i].gid == "") && Map_QM.util.changeAreaToString(mapData.decos[i]) != "") { let arr = Map_QM.util.changeAreaToString(mapData.decos[i]); entColor = parseInt(mapData.decos[i].entColor.replace("#", "0x"), 16); borderColor = parseInt(mapData.decos[i].borderColor.replace("#", "0x"), 16); let show = mapData.decos[i].name == "deco" ? "" : mapData.decos[i].name; let hollShop = []; if (mapData.decos[i].hollArea) { for (let k = 0; k < mapData.decos[i].hollArea.length; k++) { hollShop.push(Map_QM.util.changeAreaToString(mapData.decos[i].hollArea[k])); } } let mahc = this.Model_QM.MyModelShape(arr, hollShop, mapData.decos[i], entColor, borderColor, 240); mahc.xaxis = mapData.decos[i].xaxis >> 0; mahc.yaxis = mapData.decos[i].yaxis >> 0; mahc.node = mapData.decos[i].shopNav; mahc.userData = { "type": "deco", "name": show }; mahc.userData.opacity = mapData.decos[i].alphaModle / 100 || 0; this.allObj.add(mahc); } } }, /** * 渲染墙体 */ initWall: function () { let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData; //渲染 if (mapData.wallArea) { let sLen = mapData.wallArea.length; for (let i = 0; i < sLen; i++) { let arr = Map_QM.util.changeWallToString(mapData.wallArea[i]); let mahc = this.Model_QM.MyModelShape(arr, null, mapData.wallArea[i], mapData.wallArea[i].entColor || "#eaeaea", mapData.wallArea[i].borderColor || "#eaeaea", 300); mahc.userData = { "type": "wall" }; mahc.userData.opacity = mapData.wallArea[i].alphaModle / 100 || 0; this.allObj.add(mahc); } } }, /** * 渲染文本 */ initTextArea: function () { let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData; //渲染 if (mapData.svgArea) { let sLen = mapData.svgArea.length; for (let i = 0; i < sLen; i++) { let mahc = this.Model_QM.MyModelText(mapData.svgArea[i]); mahc.userData = { "type": "svg", "rot": mahc.rotation.z, "shopNum": mapData.svgArea[i].name }; this.svgObj.add(mahc); } } }, /** * 设置终点图标 */ setOverSite: function (shopX, shopY, shopZ) { if (Map_QM.endModel) { Map_QM.endModel.visible = pathCameraState == "2D" ? false : true; Map_QM.endModel.scale.x = Map_QM.endModel.scale.y = Map_QM.endModel.scale.z = 100; Map_QM.endModel.position.set(shopX, shopZ, shopY); //x,z,y Map_QM.endModel.applyMatrix4(Map_QM.sceneGap.matrix); if (Map_QM.endIcon) { Map_QM.endIcon.visible = pathCameraState == "2D" ? true : false; Map_QM.endIcon.scale.x = Map_QM.endIcon.scale.y = Map_QM.endIcon.scale.z = 100; Map_QM.endIcon.position.set(shopX, 100, shopY); //x,z,y Map_QM.endIcon.applyMatrix4(Map_QM.sceneGap.matrix); } } else { try { Map_QM.scene.traverse(item => { if (item.name == "Z-model") { Map_QM.scene.remove(item); } }); } catch (e) { console.log("traverse") } let loader2 = new THREE.GLTFLoader(); loader2.load(Map_QM.util.beforPath + "static/img/zhong.gltf", function (collada2) { collada2.scene.traverse(function (child2) { if (child2.name == "object_1" || child2.name == "object_2" || child2.name == "object_3" || child2.name == "object_4" || child2.name == "object_6" || child2.name == "object_11" || child2.name == "object_21" || child2.name == "object_31" || child2.name == "object_41") { child2.material = new THREE.MeshBasicMaterial({ color: 0xFF464E, transparent: true }); } if (child2.name == "object_5" || child2.name == "object_51") { child2.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }); } }); collada2.scene.scale.x = collada2.scene.scale.y = collada2.scene.scale.z = 100; if (shopX != 0 && shopY != 0) { collada2.scene.position.set(shopX, shopZ, shopY); //x,z,y } collada2.scene.applyMatrix4(Map_QM.sceneGap.matrix); collada2.scene.renderOrder = 200; collada2.scene.name = "Z-model"; Map_QM.endModel = collada2.scene; Map_QM.scene.add(collada2.scene); Map_QM.endModel.visible = pathCameraState == "2D" ? false : true; }); let spriteMap = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/Z.png"); let spriteMaterial = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 map: spriteMap, depthTest: true, transparent: true, alphaTest: 0.5 }); Map_QM.endIcon = new MySprite_QM(spriteMaterial); Map_QM.endIcon.scale.set(100, 100, 1); Map_QM.endIcon.center = new THREE.Vector2(0.5, 0); Map_QM.endIcon.position.set(shopX, 100, shopY); Map_QM.endIcon.applyMatrix4(Map_QM.sceneGap.matrix); Map_QM.endIcon.renderOrder = 300; Map_QM.endIcon.name = "Z-model"; Map_QM.endIcon.visible = pathCameraState == "2D" ? true : false; Map_QM.scene.add(Map_QM.endIcon); } }, /** * 设置起点图标 */ setStartSite: function (shopX, shopY, shopZ) { let _this = this; if (Map_QM.qiModel) { Map_QM.qiModel.position.set(shopX, -1 * shopY, shopZ); _this.allObj.add(Map_QM.qiModel) Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ); _this.allObj.add(Map_QM.qiIcon) Map_QM.dirIcon.position.set(shopX, -1 * shopY, shopZ); _this.allObj.add(Map_QM.dirIcon) } else { new THREE.GLTFLoader().load(Map_QM.util.beforPath + "static/img/qi.gltf", function (collada) { collada.scene.traverse(function (child) { if (child.name == "object_1" || child.name == "object_3" || child.name == "object_4" || child.name == "object_31" || child.name == "object_41") { child.material = new THREE.MeshBasicMaterial({ color: 0xFFAE43, transparent: true }); } if (child.name == "object_2" || child.name == "object_21") { child.material = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true }); } }); collada.scene.scale.x = collada.scene.scale.y = collada.scene.scale.z = 100; collada.scene.rotateX(Math.PI / 2); if (shopX != 0 && shopY != 0) { collada.scene.position.set(shopX, -1 * shopY, parseInt(Map_QM.util.buildHeight) + 5); //x,z,y } collada.scene.renderOrder = 200; collada.scene.userData.type = "start"; Map_QM.qiModel = collada.scene; _this.allObj.add(collada.scene); //-------------------------------------------------------------- let spriteMap = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/Q.png"); let spriteMaterial = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 map: spriteMap, depthTest: true, transparent: true, alphaTest: 0.5 }); Map_QM.qiIcon = new MySprite_QM(spriteMaterial); Map_QM.qiIcon.scale.set(80, 80, 1); Map_QM.qiIcon.center = new THREE.Vector2(0.5, 0); Map_QM.qiIcon.position.set(shopX, -1 * shopY, shopZ + 50); Map_QM.qiIcon.renderOrder = 500; Map_QM.qiIcon.visible = false; Map_QM.qiIcon.userData.type = "start"; _this.allObj.add(Map_QM.qiIcon); let spriteMap2 = new THREE.TextureLoader().load(Map_QM.util.beforPath + "static/img/site.png"); let spriteMaterial2 = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 map: spriteMap2, depthTest: true, transparent: true, alphaTest: 0.5 }); Map_QM.dirIcon = new MySprite_QM(spriteMaterial2); Map_QM.dirIcon.scale.set(320, 320, 1); Map_QM.dirIcon.center = new THREE.Vector2(0.5, 0.5); Map_QM.dirIcon.position.set(shopX, -1 * shopY, 100); Map_QM.dirIcon.renderOrder = 500; Map_QM.dirIcon.visible = false; Map_QM.dirIcon.userData.type = "start"; _this.allObj.add(Map_QM.dirIcon); }); } }, /** * 查找线 * @param {Object} startNode * @param {Object} endNode */ isNoFindLine: function (startNode, endNode) { let no = false; for (let i = 0; i < startNode.lineArr.length; i++) { if (startNode.lineArr[i].nextNode.id == endNode.id || startNode.lineArr[i].selfNode.id == endNode.id) { no = true; break; } } return no; }, //初始化停车位 initPark: function () { let mapData = Map_QM.util.allMap[this.buildOrder].buildArr[this.floorOrder].mapData; //渲染车位 if (mapData.parkArea) { let sLen = mapData.parkArea.length; if (sLen > 0) { this.allObj.add(this.parkObj); } let shapeArr = [], materials = [], parkHeight = 1, borderColor = 0xaaaaaa; for (let i = 0; i < sLen; i++) { let arr = Map_QM.util.changeParkToString(mapData.parkArea[i]); if (arr != "") { parkHeight = Math.max(parseInt(mapData.parkArea[i].toHeight), parkHeight); borderColor = mapData.parkArea[i].borderColor; if (arr.length > 0) { let shape = new THREE.Shape(); shape.moveTo(arr[0][0], -1 * arr[0][1]); for (let k = 0; k < arr.length; k++) { shape.lineTo(arr[k][2], -1 * arr[k][3]); } shapeArr.push(shape); let meshMaterial; let color2 = new THREE.Color(mapData.parkArea[i].entColor); for (let e = 0; e < Map_QM.util.parkMaterialArr.length; e++) { if (Map_QM.util.parkMaterialArr[e].color.equals(color2)) { meshMaterial = Map_QM.util.parkMaterialArr[e]; } } if (!meshMaterial) { meshMaterial = new THREE.MeshBasicMaterial({ color: mapData.parkArea[i].entColor }); Map_QM.util.parkMaterialArr.push(meshMaterial); } materials.push(meshMaterial); if (mapData.parkArea[i].childArea && mapData.parkArea[i].childArea.length > 0) { for (let m = 0; m < mapData.parkArea[i].childArea.length; m++) { let meshMaterial0; if (mapData.parkArea[i].childArea[m].color && mapData.parkArea[i].childArea[m].color != "#FFffff") { let color2 = new THREE.Color(mapData.parkArea[i].childArea[m].color); for (let e = 0; e < Map_QM.util.parkMaterialArr.length; e++) { if (Map_QM.util.parkMaterialArr[e].color.equals(color2)) { meshMaterial0 = Map_QM.util.parkMaterialArr[e]; } } if (!meshMaterial0) { meshMaterial0 = new THREE.MeshBasicMaterial({ color: mapData.parkArea[i].childArea[m].color }); Map_QM.util.parkMaterialArr.push(meshMaterial0); } } else { meshMaterial0 = meshMaterial; } let ps = mapData.parkArea[i].childArea[m].points; let shape0 = new THREE.Shape(); // 设置开始点的位置 shape0.moveTo(ps[0].x, -1 * ps[0].y); for (let t = 0; t < ps.length; t++) { shape0.lineTo(ps[t].x, -1 * ps[t].y); } shapeArr.push(shape0); materials.push(meshMaterial0); } } } //显示车位编号 if (mapData.parkArea[i].parkNum != "NaN" && i % 10 == 0) { let shopDiv = document.createElement('div'); shopDiv.style.cssText = css_LR; shopDiv.style.visibility = "hidden"; shopDiv.textContent = mapData.parkArea[i].parkNum; let shopLabel = new THREE.CSS2DObject(shopDiv); shopLabel.name = mapData.parkArea[i].name; shopLabel.position.set(mapData.parkArea[i].xaxis >> 0, -1 * mapData.parkArea[i].yaxis >> 0, parseInt(mapData.parkArea[i].toHeight) + 1); this.labelObj.add(shopLabel); } } } let mahc = this.Model_QM.MyParkShape(shapeArr, materials, parkHeight, borderColor); this.parkObj.add(mahc); } } } /** * 渲染3D模型类 * 传入区域点list * 镂空点 howllowArr * 模型对象 options */ MyModel_QM = function () { this.xaxis = 0; this.yaxis = 0; this.node = 0; } MyModel_QM.prototype.MyParkShape = function (shapes, materials, toHeight = 5, borderColor = 0xaaaaaa) { let scanGeometry = new THREE.ShapeBufferGeometry(shapes, 1); let material; for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { let color2 = new THREE.Color(borderColor) if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { material = Map_QM.util.lineBasicMaterialArr[k]; } } if (!material) { material = new THREE.LineBasicMaterial({ color: borderColor }); //材质对象lineColor Map_QM.util.lineBasicMaterialArr.push(material); } // 创建模型 let mesh = new THREE.Mesh(scanGeometry, materials); mesh.position.z = toHeight; mesh.renderOrder = 300; mesh.userData.type = "park"; let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60); let cubeLine = new THREE.LineSegments(cubeEdges, material); mesh.add(cubeLine); return mesh; } MyModel_QM.prototype.MyModelShape = function (areaArr, howllowArr, opObj, entityColor = 0xdadada, lineColor = 0xeeeeee, indexOrder = 1) { let len = areaArr.length; if (len == 0) { return; } let alphaModle = opObj.alphaModle / 100 || 0; // 实例化shape对象 let shape = new THREE.Shape(); // 设置开始点的位置 shape.moveTo(areaArr[0][0], -1 * areaArr[0][1]); for (let i = 0; i < areaArr.length; i++) { if (areaArr[i].length == 4) { shape.lineTo(areaArr[i][2], -1 * areaArr[i][3]); } else { shape.bezierCurveTo(areaArr[i][2], -1 * areaArr[i][3], areaArr[i][4], -1 * areaArr[i][5], areaArr[i][6], -1 * areaArr[i][7]); } } let material; for (let k = 0; k < Map_QM.util.lineBasicMaterialArr.length; k++) { let color2 = new THREE.Color(lineColor) if (Map_QM.util.lineBasicMaterialArr[k].color.equals(color2)) { material = Map_QM.util.lineBasicMaterialArr[k]; } } if (!material) { material = new THREE.LineBasicMaterial({ color: lineColor }); //材质对象lineColor Map_QM.util.lineBasicMaterialArr.push(material); } if (howllowArr && howllowArr.length > 0) { for (let n = 0; n < howllowArr.length; n++) { let hole = new THREE.Path(); // 添加孔洞 hole.moveTo(howllowArr[n][0][0], -1 * howllowArr[n][0][1]); for (let k = 0; k < howllowArr[n].length; k++) { if (howllowArr[n][k].length == 4) { hole.lineTo(howllowArr[n][k][2], -1 * howllowArr[n][k][3]); } else { hole.bezierCurveTo(howllowArr[n][k][2], -1 * howllowArr[n][k][3], howllowArr[n][k][4], -1 * howllowArr[n][k][5], howllowArr[n][k][6], -1 * howllowArr[n][k][7]); } } shape.holes.push(hole); } } let scanGeometry, meshMaterial, options = { depth: parseInt(opObj.toHeight), bevelEnabled: false, curveSegments: 24 }; scanGeometry = new THREE.ExtrudeGeometry(shape, options); for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) { let color2 = new THREE.Color(entityColor); if (Map_QM.util.meshMaterialArr[e].color.equals(color2) && Map_QM.util.meshMaterialArr[e].opacity == alphaModle) { meshMaterial = Map_QM.util.meshMaterialArr[e]; } } if (!meshMaterial) { meshMaterial = new THREE.MeshPhongMaterial({ //MeshStandardMaterial MeshPhongMaterial color: entityColor, transparent: true, opacity: alphaModle, side: THREE.DoubleSide, depthTest: true }); //meshMaterial.color.convertLinearToGamma(0.4); Map_QM.util.meshMaterialArr.push(meshMaterial); } if (opObj.angleY || opObj.angleZ) { Map_QM.util.rotateYZ(scanGeometry, opObj.angleY * Math.PI / 180, opObj.angleZ * Math.PI / 180); } // 创建模型 let mesh = new THREE.Mesh(scanGeometry, meshMaterial); if (!Map_QM.util.toMapModel && opObj.type != "wall") { let cubeEdges = new THREE.EdgesGeometry(scanGeometry, 60); let cubeLine = new THREE.LineSegments(cubeEdges, material); cubeLine.renderOrder = indexOrder - 5; mesh.add(cubeLine); } if (opObj.name != "floor") { mesh.position.z = opObj.site || 0; } else { mesh.position.z = -1 * parseInt(opObj.toHeight) - 1; } mesh.castShadow = true; mesh.renderOrder = indexOrder; mesh.name = opObj.name || ""; return mesh; } MyModel_QM.prototype.MyModelText = function (svgArea) { let text = svgArea.data; const paths = new THREE.SVGLoader().parse(text).paths; const group = new THREE.Group(); group.position.x = parseInt(svgArea.xaxis); group.position.y = -1 * parseInt(svgArea.yaxis); group.position.z = parseInt(svgArea.site || 0); group.rotateX(parseInt(svgArea.angleZ) * Math.PI / 180); group.rotateY(parseInt(svgArea.angleY) * Math.PI / 180); group.rotateZ(parseInt(svgArea.angle) * Math.PI / 180); group.scale.multiplyScalar(svgArea.scale); group.scale.y *= -1; let meshMaterial; for (let e = 0; e < Map_QM.util.meshMaterialArr.length; e++) { let color2 = new THREE.Color().setHex(svgArea.entColor); if (Map_QM.util.meshMaterialArr[e].color.equals(color2) && Map_QM.util.meshMaterialArr[e].opacity == svgArea.alphaModle) { meshMaterial = Map_QM.util.meshMaterialArr[e]; } } if (!meshMaterial) { meshMaterial = new THREE.MeshStandardMaterial({ color: svgArea.entColor, opacity: parseInt(svgArea.alphaModle) / 100 }); Map_QM.util.meshMaterialArr.push(meshMaterial); } for (let i = 0; i < paths.length; i++) { const path = paths[i]; let shapes = path.toShapes(true); for (let j = 0; j < shapes.length; j++) { const shape = shapes[j]; const geometry = new THREE.ExtrudeBufferGeometry(shape, { depth: svgArea.toHeight, bevelEnabled: false, curveSegments: 24 }); const mesh = new THREE.Mesh(geometry, meshMaterial); mesh.renderOrder = 50; mesh.name = svgArea.name || ""; mesh.position.set(-svgArea.width / 2, -svgArea.height / 2, 0); group.add(mesh); } } return group; } /** * 公共设施 */ MySprite_QM = function (spriteMaterial, obj = null) { THREE.Sprite.call(this); if (obj) { this.navCode = obj.navCode; this.no = obj.no; this.facCode = obj.facCode; this.floor = obj.floorOrder; this.build = obj.buildOrder; this.site = parseInt(obj.site) || (Map_QM.util.shopHeight + 32); } this.imgUrl; this.material = (spriteMaterial !== undefined) ? spriteMaterial : new SpriteMaterial(); //图标跳动 this.jumpIcon = function () { let oldZ = this.site; let self = this; TweenMax.fromTo(self.position, 0.5, { z: oldZ }, { z: oldZ + 20, repeat: 1, onComplete: function () { TweenMax.to(self.position, 0.2, { z: oldZ }); } }); } this.reSetSite = function () { //重置位置 this.position.z = this.site; } }; MySprite_QM.prototype = Object.create(THREE.Sprite.prototype); MySprite_QM.prototype.constructor = MySprite_QM; /** * 渲染公共设施 */ Facilities_QM = function () { } Facilities_QM.prototype.renderIcon = function (obj, _this, isShow = true, ele = null) { if (obj) { let spriteMaterial; let url = Map_QM.util.beforPath + "static/img/" + obj.facCode + ".png"; if (Map_QM.util.iconUrl.length > 0) { //使用设施库 for (let i = 0; i < Map_QM.util.iconUrl.length; i++) { if (Map_QM.util.iconUrl[i].abbreviation == obj.facCode) { url = Map_QM.util.beforPath + "static/offline" + Map_QM.util.iconUrl[i].filePath } } } for (let m = 0; m < Map_QM.util.spriteMaterialArr.length; m++) { if (Map_QM.util.spriteMaterialArr[m].name == obj.facCode) { spriteMaterial = Map_QM.util.spriteMaterialArr[m]; } } if (!spriteMaterial) { let spriteMap = new THREE.TextureLoader().load(url); spriteMaterial = new THREE.SpriteMaterial({ //sizeAttenuation: false 禁止跟随鼠标缩放 map: spriteMap, depthTest: true, transparent: true, }); spriteMaterial.name = obj.facCode; Map_QM.util.spriteMaterialArr.push(spriteMaterial); } let sprite = new MySprite_QM(spriteMaterial, obj); sprite.scale.set(64, 64, 1); sprite.imgUrl = url; sprite.center = new THREE.Vector2(0.5, 0); sprite.userData = obj; sprite.userData.type = "icon"; sprite.userData.use = ele ? "2d" : "all"; sprite.userData.model = ele; sprite.userData.src = url; sprite.position.set(obj.x, -1 * obj.y, Math.max(55, parseInt(obj.site) || 0)); sprite.renderOrder = 300; sprite.visible = isShow; _this.serObj.add(sprite); if (Map_QM.util.options.iconName) { let shopDiv = document.createElement('div'); shopDiv.style.cssText = css_LR; shopDiv.innerText = obj.title; shopDiv.dataset.name = obj.title; shopDiv.dataset.nameEn = Map_QM.util.iconEn[obj.title]; let shopLabel = new THREE.CSS2DObject(shopDiv); shopLabel.position.set(obj.x, -1 * obj.y, 30); _this.iconLabel.add(shopLabel); } } } /** * 店铺LOGO地图展示类 */ ShopLogo_QM = function () { this.renderIcon = function (obj, _this, z) { if (obj) { let x = obj.xaxis >> 0; let y = -1 * obj.yaxis >> 0; let imgW = obj.imgW >> 0; let imgH = obj.imgH >> 0; new THREE.TextureLoader().load(obj.logoUrl, textu => { let planeMaterial = new THREE.MeshPhongMaterial({ map: textu, depthTest: true, transparent: true }); let planeGeometry = new THREE.PlaneGeometry(imgW, imgH); let plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.center = new THREE.Vector2(0, 0); plane.position.set(x, y, obj.site || z); plane.userData.rot = 0 plane.userData.type = "logo" plane.renderOrder = 70; _this.add(plane); }); } } } MySprite_QM.prototype.constructor = MySprite_QM; var _selfFindPath; FindPath_QM = function () { this.pathArr = []; this.lineDashed; this.lineDashed_old; //路线指引箭头皮肤 this.planeGeometry = new THREE.PlaneGeometry(128, 128); this.stop = null; this._index = 0; //寻路用 this.pathState = "init"; this.pathPlay = { _isPlay: false, get isPlay() { return this._isPlay; }, set isPlay(val) { this._isPlay = val; if (_selfFindPath && _selfFindPath.stop) { window.cancelAnimationFrame(_selfFindPath.stop); _selfFindPath.stop = null; } if (_selfFindPath && _selfFindPath.pathState == "isPlay" && _selfFindPath._index < _selfFindPath.pathArr.length) { _selfFindPath.playMoveGuide(); } } } } FindPath_QM.prototype.clearPath = function () { this.pathArr = []; if (this.lineDashed) { if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(this.lineDashed) } this.lineDashed.destroy() this.lineDashed = null } if (this.lineDashed_old) { if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(this.lineDashed_old) } this.lineDashed_old.destroy() this.lineDashed_old = null } if (Map_QM.guide) { Map_QM.guide.visible = false; if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(Map_QM.man_2d); Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(Map_QM.man_3d); } } if (_selfFindPath && _selfFindPath.stop) { window.cancelAnimationFrame(_selfFindPath.stop); } this._index = 0; this.pathState = "init"; } /** * @param {Object} startNade * @param {Object} toNade * @param {Object} callBack 回调函数 */ FindPath_QM.prototype.onFindPathAnimation = function (pathArray, floorOrder = -1) { if (pathArray && pathArray.length > 0) { this.pathArr = []; for (let j = 0; j < pathArray.length; j++) { this.pathArr.push(pathArray[j]); } this.pathState = "isPlay"; this._index = 0; if (floorOrder === -1) { floorOrder = Map_QM.util.selectFloor; } this.drawPath(floorOrder); } } FindPath_QM.prototype.drawPath = function (floorOrder) { let linePath = [] for (let i = 0; i < this.pathArr.length; i++) { if (i < this.pathArr.length) { linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]) } } //this.lineDashed.name = 'lineDash' this.lineDashed_old = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 1, 'rgb(169,181,211)', 'rgb(189, 192, 203)', true) this.lineDashed_old.renderOrder = 128 Map_QM.mapArr[Map_QM.util.selectBuild][floorOrder].allObj.add(this.lineDashed_old) //////////////////////////////////////////////////////// } FindPath_QM.prototype.updateClearPath = function () { if (this.lineDashed) { if (Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor]) { Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.remove(this.lineDashed) } this.lineDashed.destroy() this.lineDashed = null } } FindPath_QM.prototype.updateDrawPath = function () { this.updateClearPath(); let linePath = [] linePath.push([Map_QM.guide.position.x, Map_QM.guide.position.y]); for (let i = this._index; i < this.pathArr.length; i++) { if (i < this.pathArr.length) { linePath.push([this.pathArr[i].x, -1 * this.pathArr[i].y]) } } this.lineDashed = new PathLine(12, linePath, parseInt(Map_QM.util.buildHeight) + 2, 'rgb(110, 149, 254)', 'rgb(110,125,254)', false) this.lineDashed.renderOrder = 130 Map_QM.mapArr[Map_QM.util.selectBuild][Map_QM.util.selectFloor].allObj.add(this.lineDashed); } FindPath_QM.prototype.guidePathPlay = function (paths) { if (Map_QM.guide) { Map_QM.guide.renderOrder = 99; if (paths.PathPoint) { Map_QM.guide.position.x = paths.PathPoint[0].x; Map_QM.guide.position.y = -1 * paths.PathPoint[0].y; Map_QM.moveCameraBy2D(paths.PathPoint[0]); Map_QM.man_2d.position.z = parseInt(Map_QM.util.buildHeight) + 120; Map_QM.man_3d.position.z = parseInt(Map_QM.util.buildHeight) + 5; Map_QM.guide.visible = true; Map_QM.mapArr[Map_QM.util.selectBuild][paths.floor].allObj.add(Map_QM.man_2d); Map_QM.mapArr[Map_QM.util.selectBuild][paths.floor].allObj.add(Map_QM.man_3d); } } this.pathArr = paths.PathPoint; _selfFindPath = this; if (Map_QM.util.pathStateObj.isPathPlay) { this.pathPlay.isPlay = true; } } /** * 播放图标指引动画 */ FindPath_QM.prototype.playMoveGuide = function () { if (!Map_QM.guide) { return; } let px = Map_QM.guide.position.x; let py = Map_QM.guide.position.y; let targetX = _selfFindPath.pathArr[_selfFindPath._index].x - px; let targetY = -1 * _selfFindPath.pathArr[_selfFindPath._index].y - py; let dist = Math.sqrt(targetX * targetX + targetY * targetY); let df = Math.ceil(dist / Map_QM.util.options.playSpeed); let dx = (_selfFindPath.pathArr[_selfFindPath._index].x - px) / df; let dy = ((-1 * _selfFindPath.pathArr[_selfFindPath._index].y) - py) / df; let ang = 0; if (df < 2) { Map_QM.guide.position.x = _selfFindPath.pathArr[_selfFindPath._index].x; Map_QM.guide.position.y = -1 * _selfFindPath.pathArr[_selfFindPath._index].y; Map_QM.moveCameraBy2D({ x: _selfFindPath.pathArr[_selfFindPath._index].x, y: _selfFindPath.pathArr[_selfFindPath._index].y }); _selfFindPath._index++; if (_selfFindPath._index > 0 && _selfFindPath._index < _selfFindPath.pathArr.length) { Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = 0;//180; let s = Math.sqrt((_selfFindPath.pathArr[_selfFindPath._index].x - _selfFindPath.pathArr[_selfFindPath._index - 1].x) * (_selfFindPath.pathArr[_selfFindPath._index].x - _selfFindPath.pathArr[_selfFindPath._index - 1].x) + ( _selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y) * (_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y)); ang = Math.acos((_selfFindPath.pathArr[_selfFindPath._index].y - _selfFindPath.pathArr[_selfFindPath._index - 1].y) / s); if (_selfFindPath.pathArr[_selfFindPath._index].x < _selfFindPath.pathArr[_selfFindPath._index - 1].x) { Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = Math.PI - ang; } else { Map_QM.man_3d.rotation.z = Map_QM.man_2d.rotation.z = Math.PI + ang; } } let pathShop = ""; for (let t = 0; t < Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop.length; t++) { if (Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].pathIndex == _selfFindPath._index) { let shop_ = Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop pathShop = iot ? shop_.houseNumber : shop_.houseNum; let shops = Map_QM.mapArr[Map_QM.util.selectBuild][parseInt(Map_QM.forShopArr[Map_QM.util._indexPathFloor].wayShop[t].shop.floorOrder)].allObj.children; for (let i = 0; i < shops.length; i++) { let _shop = shops[i].userData.shopData; if (_shop && (iot ? _shop.houseNumber : _shop.houseNum) === pathShop) { let shopModel = shops[i]; let material = shopModel.material; shopModel.material = new THREE.MeshBasicMaterial({ color: Map_QM.util.options.navColor }); TweenMax.to(shopModel.scale, 0.8, { z: 3, yoyo: true, ease: Cubic.easeIn, onComplete: function () { if (shopModel) { TweenMax.to(shopModel.scale, 0.5, { z: 1 }); shopModel.material = material; } } }); break; } } break; } } Map_QM.dispatchEvent({ //寻路中返回小人当前所在点位 type: 'PathPlaying', data: { "shopNum": pathShop } }); } else { px += dx; py += dy; Map_QM.guide.position.x = px; Map_QM.guide.position.y = py; Map_QM.moveCameraBy2D({ x: px, y: -1 * py }); _selfFindPath.updateDrawPath() //实时绘制有效路径 await 修是 promise } if (_selfFindPath.pathPlay.isPlay && Map_QM.guide) { if (_selfFindPath._index < _selfFindPath.pathArr.length) { _selfFindPath.stop = requestAnimationFrame(_selfFindPath.playMoveGuide); } else { if (_selfFindPath && _selfFindPath.stop) { window.cancelAnimationFrame(_selfFindPath.stop); _selfFindPath.stop = null; } _selfFindPath.updateClearPath(); _selfFindPath._index = 0; if (Map_QM.guide) { Map_QM.guide.visible = false; } let myEvent = new CustomEvent('pathOver', { detail: { dx: dx, dy: dy }, }); document.dispatchEvent(myEvent); //触发导航完成事件 _selfFindPath.pathState = "pathOver"; } } }