标签:com lan data 随机 pos 优化 number 点击 表示
// 通过 moveCamera 改变 eye 和 center 来移动场景视角为大楼的正视面 moveCamera(g3d, [134, 399, 1617], [7, 40, 144], { duration: 2000, easing: t => t * t, finishFunc: () => { // 开启场景大楼模型的可透明为 true this.building.eachChild(c => { c.s({ ‘shape3d.transparent‘: true, }); }); // 大楼模型线框的颜色变化 tweenColor(this.building, ‘wf.color‘, ‘rgba(72,149,232,1)‘, ‘rgba(56,156,255,0.03)‘, { duration: 2000, easing: t => t }); // 大楼模型整体染色的颜色变化 tweenColor(this.building, ‘shape3d.blend‘, ‘rgba(120,180,255,1)‘, ‘rgba(120,180,255,0)‘, { duration: 2000, easing: t => t, finishFunc: () => { // 楼层设置为可见 this.floor.eachChild(c => { setNodeVisible(c, true); }); this.floorLighting = 1; // 显示大楼建筑信息的动画 this.showBuilding(); } }); } });
tweenColor(node, property, startColor, endColor, animParams) { animParams = animParams || {}; if (!animParams.frames && !animParams.duration) animParams.duration = 5000; if (!animParams.easing) animParams.easing = t => t; startColor = ht.Default.toColorData(startColor); endColor = ht.Default.toColorData(endColor); const dx = endColor[0] - startColor[0]; const dy = endColor[1] - startColor[1]; const dz = endColor[2] - startColor[2]; const da = endColor[3] - startColor[3]; const postAction = animParams.postAction; animParams.action = (v, t) => { const x = startColor[0] + v * dx; const y = startColor[1] + v * dy; const z = startColor[2] + v * dz; const a = (startColor[3] + v * da) / 255; node.s(property, (‘rgba(‘ + ([x, y, z, a]).join(‘, ‘)) + ‘)‘); if (postAction) postAction((‘rgba(‘ + ([x, y, z, a]).join(‘, ‘)) + ‘)‘); } return ht.Default.startAnim(animParams); }
// 面板显示 showPanel(data) { ht.Default.startAnim({ duration: 1000, easing: t => t, action: (v,t) => { data.setScaleX(data.getScaleX() + (1 - data.getScaleX()) * v); } }); } // 面板隐藏 hidePanel(data) { ht.Default.startAnim({ duration: 1000, easing: t => t, action: (v,t) => { data.setScaleX(data.getScaleX() + (0 - data.getScaleX()) * v); } }); }
elevatorAnimation(data) { const g3d = this.g3d; const tag = data.getTag(); const e = data.getElevation(); const label = data.getChildAt(0); // 判断现在所处楼层 let now = Math.ceil(e / 50); // 下一层楼层取1~7随机数 let next = randomNumber(1, 7); // 根据现在的楼层和下一个楼层,判断电梯运行的范围 let range = numBetween(now, next); this.animationElevatorMap[tag] = ht.Default.startAnim({ duration: range * 800, easing: t => t, action: (v, t) => { // 电梯运行位置设定 data.setElevation(now < next ? (e + (range * 50) * v) : (e - (range * 50) * v)); // 设置电梯楼层面板显示并根据电梯位置设定 if (!label) return; const floor = Math.ceil(data.getElevation() / 50); if (floor === label.a(‘text‘)) return; label.a(‘text‘, floor); // 手动刷新电梯面板信息 g3d.invalidateShape3dCachedImage(label); }, finishFunc: () => { // 销毁电梯间隔动画 delete this.timeoutElevatorMap[tag]; // 执行电梯间隔动画后回调电梯运行动画 this.timeoutElevatorMap[tag] = setTimeout(() => { this.elevatorAnimation1(data); }, Math.floor(Math.random() * 5000) + 2000); } }); }
park(car, key = ‘Path‘, finishFunc) { const dm = car.dm(); const tag = car.getTag(); const forwardPath = dm.getDataByTag(tag + ‘_forward‘ + key); const backwardPath = dm.getDataByTag(tag + ‘_backward‘ + key); this.animationMap[tag] = move(car, forwardPath, ‘forward‘, undefined, 24, { pathEndFunc: () => { this.animationMap[tag].stop(); this.animationMap[tag] = move(car, backwardPath, ‘backward‘, undefined, undefined, { pathEndFunc: () => { this.animationMap[tag].stop(); delete this.animationMap[tag]; if (finishFunc) finishFunc(); return true; } }); return true; } }); }
move 是节点沿着路径平滑移动的封装函数,主要参数为:
通过绘制一条运行路线的管道,ht.Default.getLineCacheInfo() 得到这条管道的点位和分割信息 cache,然后管道信息通过 ht.Default.getLineLength() 得到管道的长度,并且通过 ht.Default.getLineOffset() 来获取连线或者管道指定比例的偏移信息,从而达到移动的效果,注意的是,这里还设定了 direction 来规定动画节点的朝向,主要是为了通过 node.lookAtX() 来获取节点下一个面对的朝向的位置信息,并设置节点此时的位置,从而达到节点沿着路径平滑移动的效果。
move(node, path, direction, step = 6, interval = 75, animParams) { let cache = path.__cache__; if (!cache) cache = path.__cache__ = ht.Default.getLineCacheInfo(path.getPoints(), path.getSegments()); const len = ht.Default.getLineLength(cache); animParams = animParams || {}; const face = direction === ‘forward‘ ? ‘front‘ : direction === ‘backward‘ ? ‘back‘ : direction; let currentLen = 0; const pathEndFunc = animParams.pathEndFunc; const action = animParams.action; animParams.action = (v, t) => { if (currentLen >= len) { // 档 pathEndFunc 返回 true 是,认为是要结束动画, 不执行后面档 action if (pathEndFunc && pathEndFunc()) return; } currentLen = currentLen % len; const offset = ht.Default.getLineOffset(cache, currentLen); const point = offset.point; node.lookAtX([point.x, node.getElevation(), point.z], face); node.p3(point.x, node.getElevation(), point.z); currentLen = currentLen + step; if (action) action(); }; return loop(animParams.action, interval); }
与此同时,我们还可以看到车辆行驶到车位或者离开时,车位上方的红绿灯则表示着这个车位的停放信息,是根据车辆的情况实时设定车位的状况,通过改变其信号灯 image 的 json 图标并手动刷新缓存来实现的。而缓存机制对于整体场景的流畅度是至关重要的,对于一些不必要实时刷新的面板信息,我们可以采取缓存的方式,并且在下一次更新的时候调用 Graph3dView.invalidateShape3dCachedImage(node)来手动刷新这个节点,从而大大提高了场景的性能,有关 3D 面板的属性可以参考 <HT 的 3D 手册 billboard 公告板>。
updateLight(view, light, color) { light.s(‘shape3d.image‘, ‘symbols/parking/‘ + color + ‘Light.json‘); view.invalidateShape3dCachedImage(light); }
标签:com lan data 随机 pos 优化 number 点击 表示
原文地址:https://www.cnblogs.com/htdaydayup/p/12638955.html