123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- <template>
- <div class="container">
- <div>
- <canvas id="enlargeCopy" width="1200" height="600" tabindex="0"/>
- <canvas id="enlarge" width="200" height="200" tabindex="0"/>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { SGraphScene, SGraphView, SImageItem } from "@persagy-web/graph";
- import { Component, Vue } from "vue-property-decorator";
- import {SPoint, SColor, SPainter, SRect} from "@persagy-web/draw/lib";
- import {SObject, SMouseButton, SMouseEvent} from "@persagy-web/base/lib";
- import { SFloorParser } from "@persagy-web/big/lib";
- class LargeView extends SGraphView {
- // 记录左键按下位置
- private _leftKeyPos: SPoint = new SPoint();
- // 可视区域即 大图中展示的区域 在 标准视图中的位置及大小
- // 可视区域宽度
- _rectW: number = 200;
- get rectW():number{
- return this._rectW;
- }
- set rectW(v:number) {
- this._rectW = v;
- this.update()
- }
- // 可视区域高度
- _rectH: number = 100;
- get rectH():number{
- return this._rectH;
- }
- set rectH(v:number) {
- this._rectH = v;
- this.update()
- }
- // 可视区域中心点
- rectC: SPoint = new SPoint(100, 100);
- // 可视区域描述的矩形
- rect: SRect = new SRect();
- // 鼠标按下的点是否在区域内
- inRect: boolean = false;
- /**
- * 鼠标按下事件
- *
- * @param event 事件参数
- */
- protected onMouseDown(event: MouseEvent): void {
- let se = new SMouseEvent(event);
- // 判断是否在可视区域内
- if (this.rect.contains(event.offsetX, event.offsetY)) {
- this.inRect = true;
- }
- // 设置可视区域中心点
- this.rectC.x = event.offsetX;
- this.rectC.y = event.offsetY;
- this.update();
- // 按下鼠标左键
- if (se.buttons & SMouseButton.LeftButton) {
- this._leftKeyPos.x = se.x;
- this._leftKeyPos.y = se.y;
- }
- // 将事件对象中的坐标转为场景坐标,并抛出事件
- const ev = this.toSceneMotionEvent(event);
- this.$emit('viewMouseMove', ev);
- }
- /**
- * 鼠标移动事件
- *
- * @param event 事件参数
- */
- protected onMouseMove(event: MouseEvent): void {
- // 按下的点如果在可视区域内,则执行移动可视区域方法
- if (this.inRect) {
- this.rectC.x = event.offsetX;
- this.rectC.y = event.offsetY;
- const ev = this.toSceneMotionEvent(event);
- this.$emit('viewMouseMove', ev);
- this.update();
- }
- }
- /**
- * 鼠标抬起事件
- *
- * @param event 事件参数
- */
- protected onMouseUp(event: MouseEvent): void {
- // 按键抬起时 初始化值
- this.inRect = false;
- }
- /**
- * 绘制前景
- *
- * @param painter 绘制对象
- */
- protected drawForeground(painter: SPainter): void {
- // 设置画笔,画刷样式
- painter.pen.color = new SColor('#efb42f');
- painter.pen.lineWidth = 2;
- painter.brush.color = new SColor('#efb42f38');
- // 绘制可视区域
- this.rect = new SRect(this.rectC.x - this.rectW / 2, this.rectC.y - this.rectH / 2, this.rectW, this.rectH);
- painter.drawRect(this.rect);
- }
- }
- @Component
- export default class GIFCanvas extends Vue {
- json: string = require('../../../public/assets/map/3.json');
- viewCopy: SGraphView | null = null;
- view: LargeView | null = null;
- /**
- * 页面挂载
- */
- mounted(): void {
- // 1.实例化2个视图
- this.view = new LargeView('enlarge'); // 标准视图
- this.viewCopy = new SGraphView('enlargeCopy'); // 放大视图
- // 实例化1个场景
- const scene = new SGraphScene();
- // 在场景中添加楼层平面图
- let parser = new SFloorParser();
- // @ts-ignore
- parser.parseData(JSON.parse(JSON.stringify(this.json.EntityList[0].Elements)));
- parser.spaceList.forEach(t => {scene.addItem(t);t.fillColor=new SColor('#47bbde75');t.connect('onMouseDown', this, this.spaceClick)});
- // 监听标准视图的事件, 回调函数是 mouseMove
- this.view.connect('viewMouseMove', this, this.mouseMove);
- // 先将场景设置到放大视图中
- this.viewCopy.scene = scene;
- // 再设置到标准视图中
- this.view.scene = scene;
- // 场景适配标准视图,
- this.view.fitSceneToView(1);
- // 设置放大视图为此时标准视图的 6 倍, 注意 6 = 1200 / 200; 1200是放大视图的宽,200 是标准视图中 可视区域的宽
- this.viewCopy.scale = 6 * this.view.scale;
- // 设置标准视图不可放缩
- this.view.scalable = false;
- // 监听放大视图中滚轮放缩事件, wheelScale 是回调
- this.viewCopy.connect('onMouseWheel', this, this.wheelScale);
- // 监听放大视图中滚轮按下拖动事件, midMouseMove 是回调
- this.viewCopy.connect('midMouseMove', this, this.midMouseMove);
- // 将标准视图中 可视区域的中心点坐标转为场景坐标
- const p1 = this.view.mapToScene(this.view.rectC.x, this.view.rectC.y);
- // 在放大视图中 将场景定位到 相应位置
- this.locationGraphy(p1);
- }
- // 步骤5
- mouseMove(item: SObject, ev: any[]) {
- const p = ev[0];
- this.locationGraphy(p)
- }
- // 定位点到放大视图的中心点
- locationGraphy(point:any) {
- let centerX = (this.viewCopy!!.width / 2) - point.x * this.viewCopy!!.scale;
- let centerY = (this.viewCopy!!.height / 2) - point.y * this.viewCopy!!.scale;
- this.viewCopy!!.origin = new SPoint(centerX, centerY)
- }
- // 放大视图 滚轮放缩事件回调
- wheelScale(item: SObject, ev: any[]) {
- // ev[0] view 的放缩比例
- // ev[1] true 上滚 放大
- if (this.view && this.viewCopy) {
- if (ev[1]) {
- this.view.rectW /= this.viewCopy.wheelZoom;
- this.view.rectH /= this.viewCopy.wheelZoom;
- } else {
- this.view.rectW *= this.viewCopy.wheelZoom;
- this.view.rectH *= this.viewCopy.wheelZoom;
- }
- }
- }
- // 放大视图 滚轮按下拖动回调
- midMouseMove(item: SObject, ev: any[]) {
- if (this.viewCopy && this.view) {
- const p = this.viewCopy.mapToScene(600, 300);
- const p2 = this.view.mapFromScene(p.x, p.y);
- this.view.rectC.x = p2.x;
- this.view.rectC.y = p2.y;
- this.view.update();
- }
- }
- spaceClick(){
- console.log(arguments)
- }
- }
- </script>
- <style scoped lang="less">
- .container{
- & > div{
- position: relative;
- height: 600px;
- }
- canvas {
- position: absolute;
- }
- #enlarge{
- background: #fff;
- }
- }
- </style>
|