eagleEyeMap.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <div class="container">
  3. <div>
  4. <canvas id="enlargeCopy" width="1200" height="600" tabindex="0"/>
  5. <canvas id="enlarge" width="200" height="200" tabindex="0"/>
  6. </div>
  7. </div>
  8. </template>
  9. <script lang="ts">
  10. import { SGraphScene, SGraphView, SImageItem } from "@persagy-web/graph";
  11. import { Component, Vue } from "vue-property-decorator";
  12. import {SPoint, SColor, SPainter, SRect} from "@persagy-web/draw/lib";
  13. import {SObject, SMouseButton, SMouseEvent} from "@persagy-web/base/lib";
  14. import { SFloorParser } from "@persagy-web/big/lib";
  15. class LargeView extends SGraphView {
  16. // 记录左键按下位置
  17. private _leftKeyPos: SPoint = new SPoint();
  18. // 可视区域即 大图中展示的区域 在 标准视图中的位置及大小
  19. // 可视区域宽度
  20. _rectW: number = 200;
  21. get rectW():number{
  22. return this._rectW;
  23. }
  24. set rectW(v:number) {
  25. this._rectW = v;
  26. this.update()
  27. }
  28. // 可视区域高度
  29. _rectH: number = 100;
  30. get rectH():number{
  31. return this._rectH;
  32. }
  33. set rectH(v:number) {
  34. this._rectH = v;
  35. this.update()
  36. }
  37. // 可视区域中心点
  38. rectC: SPoint = new SPoint(100, 100);
  39. // 可视区域描述的矩形
  40. rect: SRect = new SRect();
  41. // 鼠标按下的点是否在区域内
  42. inRect: boolean = false;
  43. /**
  44. * 鼠标按下事件
  45. *
  46. * @param event 事件参数
  47. */
  48. protected onMouseDown(event: MouseEvent): void {
  49. let se = new SMouseEvent(event);
  50. // 判断是否在可视区域内
  51. if (this.rect.contains(event.offsetX, event.offsetY)) {
  52. this.inRect = true;
  53. }
  54. // 设置可视区域中心点
  55. this.rectC.x = event.offsetX;
  56. this.rectC.y = event.offsetY;
  57. this.update();
  58. // 按下鼠标左键
  59. if (se.buttons & SMouseButton.LeftButton) {
  60. this._leftKeyPos.x = se.x;
  61. this._leftKeyPos.y = se.y;
  62. }
  63. // 将事件对象中的坐标转为场景坐标,并抛出事件
  64. const ev = this.toSceneMotionEvent(event);
  65. this.$emit('viewMouseMove', ev);
  66. }
  67. /**
  68. * 鼠标移动事件
  69. *
  70. * @param event 事件参数
  71. */
  72. protected onMouseMove(event: MouseEvent): void {
  73. // 按下的点如果在可视区域内,则执行移动可视区域方法
  74. if (this.inRect) {
  75. this.rectC.x = event.offsetX;
  76. this.rectC.y = event.offsetY;
  77. const ev = this.toSceneMotionEvent(event);
  78. this.$emit('viewMouseMove', ev);
  79. this.update();
  80. }
  81. }
  82. /**
  83. * 鼠标抬起事件
  84. *
  85. * @param event 事件参数
  86. */
  87. protected onMouseUp(event: MouseEvent): void {
  88. // 按键抬起时 初始化值
  89. this.inRect = false;
  90. }
  91. /**
  92. * 绘制前景
  93. *
  94. * @param painter 绘制对象
  95. */
  96. protected drawForeground(painter: SPainter): void {
  97. // 设置画笔,画刷样式
  98. painter.pen.color = new SColor('#efb42f');
  99. painter.pen.lineWidth = 2;
  100. painter.brush.color = new SColor('#efb42f38');
  101. // 绘制可视区域
  102. this.rect = new SRect(this.rectC.x - this.rectW / 2, this.rectC.y - this.rectH / 2, this.rectW, this.rectH);
  103. painter.drawRect(this.rect);
  104. }
  105. }
  106. @Component
  107. export default class GIFCanvas extends Vue {
  108. json: string = require('../../../public/assets/map/3.json');
  109. viewCopy: SGraphView | null = null;
  110. view: LargeView | null = null;
  111. /**
  112. * 页面挂载
  113. */
  114. mounted(): void {
  115. // 1.实例化2个视图
  116. this.view = new LargeView('enlarge'); // 标准视图
  117. this.viewCopy = new SGraphView('enlargeCopy'); // 放大视图
  118. // 实例化1个场景
  119. const scene = new SGraphScene();
  120. // 在场景中添加楼层平面图
  121. let parser = new SFloorParser();
  122. // @ts-ignore
  123. parser.parseData(JSON.parse(JSON.stringify(this.json.EntityList[0].Elements)));
  124. parser.spaceList.forEach(t => {scene.addItem(t);t.fillColor=new SColor('#47bbde75');t.connect('onMouseDown', this, this.spaceClick)});
  125. // 监听标准视图的事件, 回调函数是 mouseMove
  126. this.view.connect('viewMouseMove', this, this.mouseMove);
  127. // 先将场景设置到放大视图中
  128. this.viewCopy.scene = scene;
  129. // 再设置到标准视图中
  130. this.view.scene = scene;
  131. // 场景适配标准视图,
  132. this.view.fitSceneToView(1);
  133. // 设置放大视图为此时标准视图的 6 倍, 注意 6 = 1200 / 200; 1200是放大视图的宽,200 是标准视图中 可视区域的宽
  134. this.viewCopy.scale = 6 * this.view.scale;
  135. // 设置标准视图不可放缩
  136. this.view.scalable = false;
  137. // 监听放大视图中滚轮放缩事件, wheelScale 是回调
  138. this.viewCopy.connect('onMouseWheel', this, this.wheelScale);
  139. // 监听放大视图中滚轮按下拖动事件, midMouseMove 是回调
  140. this.viewCopy.connect('midMouseMove', this, this.midMouseMove);
  141. // 将标准视图中 可视区域的中心点坐标转为场景坐标
  142. const p1 = this.view.mapToScene(this.view.rectC.x, this.view.rectC.y);
  143. // 在放大视图中 将场景定位到 相应位置
  144. this.locationGraphy(p1);
  145. }
  146. // 步骤5
  147. mouseMove(item: SObject, ev: any[]) {
  148. const p = ev[0];
  149. this.locationGraphy(p)
  150. }
  151. // 定位点到放大视图的中心点
  152. locationGraphy(point:any) {
  153. let centerX = (this.viewCopy!!.width / 2) - point.x * this.viewCopy!!.scale;
  154. let centerY = (this.viewCopy!!.height / 2) - point.y * this.viewCopy!!.scale;
  155. this.viewCopy!!.origin = new SPoint(centerX, centerY)
  156. }
  157. // 放大视图 滚轮放缩事件回调
  158. wheelScale(item: SObject, ev: any[]) {
  159. // ev[0] view 的放缩比例
  160. // ev[1] true 上滚 放大
  161. if (this.view && this.viewCopy) {
  162. if (ev[1]) {
  163. this.view.rectW /= this.viewCopy.wheelZoom;
  164. this.view.rectH /= this.viewCopy.wheelZoom;
  165. } else {
  166. this.view.rectW *= this.viewCopy.wheelZoom;
  167. this.view.rectH *= this.viewCopy.wheelZoom;
  168. }
  169. }
  170. }
  171. // 放大视图 滚轮按下拖动回调
  172. midMouseMove(item: SObject, ev: any[]) {
  173. if (this.viewCopy && this.view) {
  174. const p = this.viewCopy.mapToScene(600, 300);
  175. const p2 = this.view.mapFromScene(p.x, p.y);
  176. this.view.rectC.x = p2.x;
  177. this.view.rectC.y = p2.y;
  178. this.view.update();
  179. }
  180. }
  181. spaceClick(){
  182. console.log(arguments)
  183. }
  184. }
  185. </script>
  186. <style scoped lang="less">
  187. .container{
  188. & > div{
  189. position: relative;
  190. height: 600px;
  191. }
  192. canvas {
  193. position: absolute;
  194. }
  195. #enlarge{
  196. background: #fff;
  197. }
  198. }
  199. </style>