vue 中 canvas 和svg合用制作地图

<template>
  <div class="contents">
    <div class="lefttop1-title">区域</div>
    <img id="police" src="../assets/police.svg" style="display:none;"  width="395px" height="343px">
    <div id="contentMap" style="width: 100%;height: 95%;">
      <canvas id="areaCanvas" width="395px" height="343px" style="width:90%;height:90%;margin-left:20px;"></canvas>
    </div>
  </div>
</template>

<script>
  //vue中点在不规则图形中的判断
    var inside = require( 'point-in-polygon' );
    import {generatePolygon} from '../api/index.js'
    export default {
        data () {
            return {
                collectionArr: [],
            }
        },
        mounted () {
            // 地图坐标
          generatePolygon().then(response => {
            this.collectionArr = response.data;
            this.drawPolygons();
          });

        },
        methods: {
//			地图
            drawPolygons: function () {
              var canvas = document.getElementById( 'areaCanvas' );
              if ( null == canvas || !canvas.getContext ) return;
              var ctx = canvas.getContext( "2d" );

              var  img=document.getElementById("police");
              if(img.complete){
                ctx.drawImage(img, 0, 0);
              }else{
                img.onload = function() {
                  ctx.drawImage(img, 0, 0);
                }
              }

              //鼠标移动事件
              this.canvasMousemoveEvent( canvas, ctx );

              //click事件
              this.canvasClickEvent( canvas );
            },
            canvasMousemoveEvent: function ( canvas, ctx ) {
                var _this = this;
                canvas.onmousemove = function ( e ) {
                  //清除绘制图形
                  _this.clearPolygon(ctx,canvas);
                  //  ctx.clearRect( 0, 0, canvas.width, canvas.height );
                    var location = _this.getLocation( canvas, e.clientX, e.clientY );
                    _this.drawPolygonByPoint( ctx, location, e ,canvas);
                };
            },
            canvasClickEvent: function ( canvas ) {
                var _this = this;
                canvas.onclick = function ( e ) {
                    var location = _this.getLocation( canvas, e.clientX, e.clientY );
                    var count = 0;
                    _this.collectionArr.map( obj => {
                      var pointsArr = obj.polygon;
                        count++;
                        if ( location != null && inside( location, pointsArr ) == true ) {
                            alert(obj.name);
                        }
                    } );
                };
            },
            drawPolygonByPoint: function ( ctx, location, e ,canvas) {
                //清除title
                this.clearTitle();
                this.collectionArr.map( obj => {
                  var pointsArr = obj.polygon;
                    if ( location != null && inside( location, pointsArr ) == true ) {
                        //绘制高亮图形
                        this.drawHighLightPolygon( ctx, pointsArr,canvas );
                        this.displayTitle(e,obj.name);
                    }
                } );
            },
            clearTitle: function () {
                var div = document.getElementById( 'title' );
                if ( div != null ) {
                  document.body.removeChild(div);
                }
            },
            displayTitle: function ( e ,name) {
                var div = document.createElement( "div" );
                div.setAttribute( "id", "title" );
                div.style.position = "absolute";
                div.style.left = e.clientX + 10 + "px";
                div.style.top = e.clientY + "px"
                div.innerText = name;
                div.style.backgroundColor = "gray";
                div.style.zIndex = "9999";
                document.body.appendChild( div );
            },
            drawHighLightPolygon: function ( ctx, pointsArr ,canvas) {
                ctx.beginPath();
                for ( let i = 0; i < pointsArr.length; i++ ) {
                  var pointX = Math.round(canvas.width * pointsArr[ i ][ 0 ])+1;
                  var pointY = Math.round(canvas.height * pointsArr[ i ][ 1 ])+1;
                  ctx.lineWidth=2;
                    if ( i == 0 ) {
                        ctx.moveTo( pointX, pointY );
                    } else if ( i < pointsArr.length - 1 ) {
                        ctx.lineTo( pointX, pointY );
                    } else {
                        ctx.lineTo( pointX, pointY );
                        ctx.strokeStyle = "#FF7F00";

                        ctx.closePath();
                        ctx.stroke();
                    }
                }
            },
          clearPolygon: function(ctx,canvas){
            ctx.clearRect( 0, 0, canvas.width, canvas.height );
            var  img=document.getElementById("police");
            ctx.drawImage(img, 0, 0);
          },
            getLocation: function ( canvas, x, y ) {
                var bbox = canvas.getBoundingClientRect();
                return [ ( x - bbox.left ) * ( canvas.width / bbox.width )/canvas.width, ( y - bbox.top ) * ( canvas.height / bbox.height )/canvas.height ];
                /*
                 * 此处不用下面两行是为了防止使用CSS和JS改变了canvas的高宽之后是表面积拉大而实际
                 * 显示像素不变而造成的坐标获取不准的情况
                x: (x - bbox.left),
                y: (y - bbox.top)
                */
            },

        }
    }
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .contents {
      float: left;
      height: 98.5%;
      width: 41.3%;
      border: 1px solid rgba(15, 208, 198, 0.50);
      box-shadow: inset 0 2px 19px 0 rgba(15, 208, 198, 0.80);
      margin-left: 1.4%;
      margin-right: 1.4%;
    }
    .lefttop1-title{
      text-align: center;
      color: #0FD0C6;
      font-size: 12px;
      background: url(../assets/Group.png) no-repeat;
      width: 170px;
      line-height: 25px;
      display: inline-block;
    }
</style>


其中police.svg做地图,鼠标移动到某一区域,高亮显示该区域(在底图上只画出该区域)。
所有区域的坐标点使用svg导出的相对坐标,在画图时要根据canvas画布转换成绝对坐标。
collectionArr数据结构:
collectionArr: [{name:'区域一',polygon:[[0.0123,0.1723],...]},{name:'区域二',polygon:[[0.0123,0.1723],...]},...]

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值