index.vue 9.93 KB
<template>
  <div class="pview">
    <div class="painter" ref="painter"></div>
    <!-- 右键操作 S -->
    <ul class="action" ref="action">
      <!-- <li class="fill">
        <label>填充色:</label>
        <div class="item">
          <el-color-picker show-alpha size="medium" v-model="fillColor" @change="setChangeColor"></el-color-picker>
        </div>
      </li>
      <li class="fill">
        <label>缩放:</label>
        <div class="item">
          <el-slider :format-tooltip="formatter" :min="1" :max="100" v-model="scaleVal" @change="setChangeScale"></el-slider>
        </div>
      </li>
      <li class="fill">
        <label>旋转:</label>
        <div class="item">
          <el-slider :min="0" :max="360" v-model="rotateVal" @change="setChangeRotate"></el-slider>
        </div>
      </li> -->
      <li class="btns">
        <el-button size="small" type="danger" @click="delGroup">删除</el-button>
        <el-button size="small" @click="closeAction">取消</el-button>
      </li>
    </ul>
    <!-- 右键操作 E -->
  </div>
</template>
<script>
import _ from 'underscore';
import zrender from 'zrender';
import drawMap from './drawMap';
/**********操作缓存****************/
/**************************/
export default {
  extends: drawMap,
  data() {
    return {
      pointList:[],//当前绘制的图形点位列表
      groupList:[], //图形数组
      zr: {}, //绘图实例对象
      baseColor: 'transparent',
      strokeColor:'rgba(0,0,0,0.4)',
      /*********************************/
      fillColor: '#9d9c9c',
      scaleVal: 10, //缩放
      rotateVal: 0, //旋转角度
      /*********************************/
      groupObj: {},
    }
  },
  components: {

  },
  watch: {

  },
  methods: {
    clearPainter() {
      this.zr.clear();
      this.groupList = [];
      this.pointList = [];
    },
    formatter(value) {
      return value / 10;
    },
    setChangeColor(color) {
      let { polyline } = this.groupObj;
      polyline.attr({
        style: {
          stroke: color,
          fill: color
        }
      });
    },
    setChangeScale(scale) {
      let { polyline } = this.groupObj;
      polyline.attr({
        scale: [scale / 10, scale / 10],
      });
    },
    setChangeRotate(rotate) {
      let { polyline } = this.groupObj;
      polyline.attr({
        rotation: rotate * Math.PI / 180,
      });
    },
    delGroup() {
      this.groupList = _.filter(this.groupList, item => {
        console.info(item.id,this.groupObj.id)  
        return item.id != this.groupObj.id
      })
      this.zr.remove(this.groupObj);
      this.closeAction();
    },
    closeAction() {
      this.$refs.action.style.display = 'none';
    },
    bindingEvt() {
      let that = this;
      let group ;
      this.zr.on('click', evt => {
        this.closeAction();
        let point = [evt.event.zrX, evt.event.zrY];
        this.pointList.push(point);
        if (this.pointList.length == 1) { //第一次点击,创建Group
           let points = zrender.util.clone(this.pointList);
           group = this.createGroup({points,fill:that.baseColor});
        }
        this.drawPolyline(group,this.pointList);
      })
      this.zr.on('mousemove', evt => {
        if (this.pointList.length == 0) return false;
        let point = [evt.event.zrX, evt.event.zrY];
        this.drawPolyline(group,this.pointList.concat([point]));
      });
    },
    drawPolyline(group,points) {
      group.polyline.setShape({
        points: points
      });
    },
    createGroup(gdata) {
      let that = this;
      let points = gdata.points;
      let fill = gdata.fill;
      let position = gdata.position;
      /*******************************/
      let group = new zrender.Group({
          complete:false,
          position:position||[0,0]
      });
      let polyline = this.createPolyline({
          stroke:that.strokeColor,
          fill:fill,
          points:points
      })
      group.id = gdata.id||Date.now().toString(36);
      group.add(polyline);
      group.polyline = polyline;
      group.fill = gdata.fill;
      group.data = gdata;
      if(this.isEdit&&points.length==1){
        let circle = that.createCircle(group,points[0]);
        group.add(circle)
      }else{
        this.drawText(group,gdata);
        
      }
      group.on('click', function(evt){
        if(!that.isEdit){
            that.groupLeft(evt,this); 
            evt.cancelBubble = true;
            return false;
        }
        if (that.pointList.length == 1) {
          //evt.cancelBubble = true;
        }
      });
      let action = this.$refs.action;
      /*action.onmouseleave = ()=>{
          action.style.display = 'none'
      }*/
      group.on('contextmenu', function (evt) {
        if(!that.isEdit){
            that.groupRight(evt,this);
            evt.stop();
            return false
        }  
        if (that.pointList.length > 0) {
          evt.stop();
          return false;
        }
        action.style.display = 'block';
        action.style.left = (evt.offsetX - 5) + 'px'
        action.style.top = (evt.offsetY - 5) + 'px'
        evt.stop();
        that.setCurrentGroup(this);
        return false;
      })
      this.zr.add(group);
      this.groupList.push(group);
      return group;
    },
    createCircle(group,point){
        let that = this;
        let circle = new zrender.Circle({
            style: {
            fill: 'transparent',
            stroke: 'rgba(0,0,0,0.4)',
            lineWidth: 2
            },
            shape: {
            cx: point[0],
            cy: point[1],
            r: 10
            }
        });
        circle.on('click', evt => {
            evt.cancelBubble = true;
            that.pointList.push(that.pointList[0]);
            group.remove(circle);
            if (that.pointList.length > 3) {
                this.drawPolyline(group,that.pointList);
                this.drawText(group);
            } else {
                this.zr.remove(group)
            }
            that.pointList = [];
        });
        return circle;
    },
    createPolyline(params){
        let that = this;
        return new zrender.Polyline({
            x: 0,
            y: 0,
            origin: [0, 0],
            //cursor:'move',
            draggable: false,
            style: {
                stroke: params.stroke,
                fill: params.fill||that.baseColor,
                lineWidth: 3
            },
            shape: {
            points: params.points,
            smooth: 0.01
            }
        });
         
    },
    drawText(group,data={}) {
      let that = this;  
      let client = group.getBoundingRect();
      let content = `{name|${data.zoneName||''}}\n{num|${isNaN(data.num)?'':data.num}}`;
      let text = new zrender.Text({
        position: [client.x, client.y],
        style: {
          x: client.width / 2,
          y: client.height / 2 - (isNaN(data.num)?0:14),
          width: client.width,
          height: client.height,
          textAlign: 'middle',
          verticalAlign: 'middle',
          //textShadowBlur: 3,
          textShadowColor: '#893e95',
          //textShadowOffsetX: 3,
          //textShadowOffsetY: 3,
          text: content,
          fill: '#c0f',
          fontSize: 14,
          rich: {
                name: {
                    
                    textLineHeight:16
                },
                num:{
                   
                   textFill:'#850747'
                }
          }
        }
      });
      //text.setClipPath(curGroup.polyline)
      //this.setDragaAble(text)
      group.add(text);
      group.text = text;
      group.complete = true;//图像已经绘制完毕
      group.polyline.attr({
        origin: [client.x + client.width / 2, client.y + client.height / 2]
      });
      if(that.isEdit){
          that.setDragaAble(group);
      }else{
        group.on('mousemove', function(evt){
           that.groupMove(evt,this);  
        });
        group.on('mouseover', function(evt){
           that.groupOver(evt,this);  
        });
        group.on('mouseout', function(evt){
           that.groupOut(evt,this);  
        });
      }
    },
    setCurrentGroup(group) {
      this.groupObj = _.find(this.groupList, item => {
        return item.id == group.id;
        
      });

      this.fillColor = this.groupObj.polyline.style.fill;
    },
    setDragaAble(el, popup) {
      let isDown = false,
        downPoint = [],
        initPoint = [];
      el.on('mousedown', evt => {
        isDown = true;
        evt.cancelBubble = true;
        downPoint = [evt.event.zrX, evt.event.zrY];
        initPoint = zrender.util.clone(el.position);
        evt.cancelBubble = true;
      });
      el.on('mousemove', evt => {
        if (isDown) {
          evt.cancelBubble = true;
          let pos = [evt.event.zrX - downPoint[0], evt.event.zrY - downPoint[1]];
          el.attr('position', [initPoint[0] + pos[0], initPoint[1] + pos[1]]);
        }
      });
      el.on('mouseup', evt => {
        evt.cancelBubble = true;
        isDown = false;
      });
      this.zr.on('mouseup', function () {
        isDown = false;
      })
    },
    
  },
  created() {
     window.draw = this;
  },
  mounted() {
    
  }
}

</script>
<style scoped>
.pview {
  position: relative;
  width: 100%;
}

.pview .painter {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.pview .action {
  position: absolute;
  display: none;
  left: 0;
  top: 0;
  background: #fff;
  z-index: 9;
  padding: 0px 0px;
  border: 1px solid #ccc;
  /* min-width: 300px; */
}

.pview .action li {
  font-size: 16px;
  line-height: 1.4;
  padding: 6px 10px;
  letter-spacing: 1px;
  border-bottom: 1px solid #ececec;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 36px;
}

.pview .action li label {
  width: 80px;
  text-align: right;
  padding-right: 10px;
  box-sizing: border-box;
}

.pview .action li .item {
  flex: 1;
}

.pview .action li.btns {
  justify-content: flex-end;
}

.pview .action li:hover {
  background-color: #ececec;
}
</style>