<template>
  <el-dialog
    :visible.sync="visible"
    :append-to-body="visible"
    :modal="false"
    title="图片预览"
    width="20%"
    @opened="openCanvas"
    @close="closeDialog"
    style="display: flex; align-items: center;justify-content: center;"
    v-if="visible">
    <div>
      <div v-if="prodType === '小卡'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0465 + 'px'}">
      </div>
      <div v-if="prodType === '拍立得'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0465 + 'px'}">
      </div>
      <div v-if="prodType === '直拍封面'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.02325 + 'px'}">
      </div>
      <div v-if="prodType === '票根'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0465 + 'px'}">
      </div>
      <div  v-if="prodType === '书签'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0264 + 'px'}">
      </div>
      <div v-if="prodType === '明信片'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0261 + 'px'}">
      </div>
      <div v-if="prodType === '方卡'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0232 + 'px'}">
      </div>
      <div v-if="prodType === '徽章'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0813 + 'px', borderRadius: 100 + '%'}">
      </div>
      <div v-if="prodType === '手幅'" class="previewClass" :style="{width: previewWidth + 'px', height: previewHeight + 'px', borderWidth: previewWidth * 0.0255 + 'px'}">
      </div>
      <el-image ref="previewImageRef" :src="previewPicUrl" alt="" @load="previewLoad" style="width: 100%; height: 100%"/>
    </div>
    <!--<div class="parent">
      <canvas ref="canvas" :width="clientWidth" :height="clientHeight" id="myCanvas"></canvas>
      <div class="blood" :style="{border: bloodWidth + 'px solid rgba(225,0,0, 0.3)' , width: clientWidth +'px', height: clientHeight + 'px', borderRadius: bloodRadius + '%'}"></div>
    </div>
    <div style="text-align: center;">
      <el-button @click="cropImage">保存画布</el-button>
    </div>-->

  </el-dialog>

</template>

<script>
  const statusConfig = {IDLE:0, DRAG_START:1, DRAGGING:2};
  const prodSize = {'小卡': {width: 709, height: 1087, clientScale:0.5, bloodRadio: 0.0242}, '方卡':{width: 1252, height: 1252, clientScale:0.5}, '拍立得':{width: 709, height: 1087, clientScale:0.5, bloodRadio: 0.0242},
                    '直拍封面':{width: 709, height: 1217, clientScale:0.5, bloodRadio: 0.02325}, '书签': {width: 638, height: 1819, clientScale:0.4, bloodRadio: 0.0264},'明信片':{width: 1252, height: 1819, clientScale:0.4, bloodRadio: 0.0261},
                    '徽章':{width: 839, height: 839, clientScale:0.5, bloodRadio: 0.0813, bloodRadius:100},'票根':{width: 709, height: 1489, clientScale:0.5, bloodRadio: 0.0465},'手幅':{width: 1252, height: 3614, clientScale:0.25, bloodRadio: 0.0255}}
  export default {
    name: "CanvasPreview",
    data() {
      return {
        visible: false,
        prodType: null,
        previewWidth: null,
        previewHeight: null,
        previewPicUrl: null,
        side: null,
        clientWidth: 709,
        clientHeight: 1087,
        clientScale: 0.5,
        cardItem: null,
        canvasParam:null,
        bloodWidth: 20,
        bloodRadius: 0,
        canvasInfo:{
          status: statusConfig.IDLE,
          dragTarget: {x:0,y:0,w:0,h:0},
          lastEvtPos: {x:null,y:null},
          offsetEvtPos: {x:null,y:null},
          offset: {x:0,y:0},
          scale: 1,
          scaleStep: 0.01,
          minScale: 0.5,
          maxScale: 2,
        },
        imgRef:null,
        canvas:null,
        context: null,
      };
    },
    mounted() {
    },
    methods: {
      openCanvas(){
        this.initCanvas();
        this.drawImage();
        this.addMouseListeners();
      },
      init(cardItem, previewPicUrl, prodType, side){
        this.visible = true;
        this.previewPicUrl = previewPicUrl;
        this.prodType = prodType;
        this.side = side;
        this.cardItem = cardItem;
        if(side === 'front'){
          this.canvasParam = JSON.parse(cardItem.frontCanvasParam);
        }else if(side === 'back'){
          this.canvasParam = JSON.parse(cardItem.backCanvasParam);
        }
        let prod = prodSize[prodType];
        this.clientWidth = prod.width * prod.clientScale;
        this.clientHeight = prod.height * prod.clientScale;
        this.bloodRadius = prod.bloodRadius ? prod.bloodRadius : this.bloodRadius;
        this.bloodWidth = prod.width * prod.bloodRadio;
      },
      previewLoad(event){
        this.previewWidth = event.srcElement.clientWidth;
        this.previewHeight = event.srcElement.clientHeight;
      },
      cropImage() {
        this.$confirm('确认要保存当前画布状态吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          let canvasInfo = this.canvasInfo;
          let cardItem = {cardItemId : this.cardItem.cardItemId};
          let obj =  {scale: canvasInfo.scale, offsetX: canvasInfo.offset.x, offsetY: canvasInfo.offset.y, targetX: canvasInfo.dragTarget.x, targetY: canvasInfo.dragTarget.y}
          let canvasParam = JSON.stringify(obj);
          if(this.side === 'front'){
            cardItem.frontCanvasParam = canvasParam;
          }else if(this.side === 'back'){
            cardItem.backCanvasParam = canvasParam;
          }
          this.$http({
            url: this.$http.adornUrl('/prod/orderCardItem/saveOrUpdateCanvasParam'),
            method: 'post',
            data: cardItem
          }).then(({ data }) =>{
            if(data){
              this.$message.success("保存成功");
            }else{
              this.$message.error("保存失败");
            }
          })
        });
      },
      initCanvas() {
        this.canvas = this.$refs.canvas;
        this.context = this.canvas.getContext('2d'); // 获取画布上下文
      },
      getCanvasPosition(e, offset = {x:0,y:0}){
        return {
          x: e.offsetX - offset.x,
          y: e.offsetY - offset.y
        }
      },
      render(){
        this.canvas.width = this.clientWidth;
        this.context.setTransform(this.canvasInfo.scale, 0, 0, this.canvasInfo.scale, this.canvasInfo.offset.x, this.canvasInfo.offset.y);
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
        this.drawImage();
      },
      ifInImage(pos){
        let dx = this.getDistanceX(pos.x, this.imgRef.x);
        let dy = this.getDistanceY(pos.y, this.imgRef.y);
        if(dx <= this.imgRef.width && dy <=this.imgRef.height){
          return true;
        }else{
          return false;
        }
      },
      getDistanceX(x1, x2){
        return Math.abs((x1 - x2));
      },
      getDistanceY(y1, y2){
        return Math.abs((y1 - y2));
      },
      drawImage() {
        if(!this.imgRef){
          this.imgRef = new Image();
          this.imgRef.src = this.previewPicUrl;
          if(this.canvasParam){
            this.canvasInfo.scale = this.canvasParam.scale;
            this.canvasInfo.offset.x = this.canvasParam.offsetX;
            this.canvasInfo.offset.y = this.canvasParam.offsetY;
            this.canvasInfo.dragTarget.x = this.canvasParam.targetX;
            this.canvasInfo.dragTarget.y = this.canvasParam.targetY;
          }else{
            let scaleImgWidth = this.imgRef.width * this.canvasInfo.scale;
            let scaleImgHeight = this.imgRef.height * this.canvasInfo.scale;
            if (scaleImgWidth > this.canvas.width && scaleImgHeight > this.canvas.height) {
              if(scaleImgWidth > scaleImgHeight){
                this.canvasInfo.scale =  this.canvas.height / scaleImgHeight;
              }else{
                this.canvasInfo.scale =  this.canvas.width / scaleImgWidth;
              }
            }else if(scaleImgWidth < this.canvas.width && scaleImgHeight < this.canvas.height){
              if(scaleImgWidth > scaleImgHeight){
                this.canvasInfo.scale =  this.canvas.height / scaleImgHeight;
              }else{
                this.canvasInfo.scale =  this.canvas.width / scaleImgWidth;
              }
            }
          }
          this.context.setTransform(this.canvasInfo.scale, 0,0, this.canvasInfo.scale, this.canvasInfo.offset.x,this.canvasInfo.offset.y)
          this.context.drawImage(this.imgRef, this.canvasInfo.dragTarget.x, this.canvasInfo.dragTarget.y, this.imgRef.width, this.imgRef.height); // 在画布上绘制图片
        }else{
          this.context.drawImage(this.imgRef, this.canvasInfo.dragTarget.x, this.canvasInfo.dragTarget.y, this.imgRef.width, this.imgRef.height); // 在画布上绘制图片
        }
      },
      addMouseListeners() {
        let canvas = this.$refs.canvas;
        // 监听鼠标按下事件
        canvas.addEventListener('mousedown', e => {
          let canvasPosition = this.getCanvasPosition(e, this.canvasInfo.offset);
          console.log("画笔位置", canvasPosition);
          if(this.ifInImage(canvasPosition)){
            let scaleImgWidth = this.imgRef.width * this.canvasInfo.scale;
            let scaleImgHeight = this.imgRef.height * this.canvasInfo.scale;
            if(scaleImgWidth <= this.canvas.width || scaleImgHeight <= this.canvas.height){
              return;
            }
            this.canvasInfo.status = statusConfig.DRAG_START;
            this.canvasInfo.lastEvtPos = canvasPosition;
            this.canvasInfo.offsetEvtPos = canvasPosition;
          }
        });

        //监听鼠标移动事件
        canvas.addEventListener('mousemove', e => {
          let canvasPosition = this.getCanvasPosition(e, this.canvasInfo.offset);
          if(this.canvasInfo.status === statusConfig.DRAG_START && (this.getDistanceX(canvasPosition.x, this.canvasInfo.lastEvtPos.x) > 5 || this.getDistanceY(canvasPosition.y, this.canvasInfo.lastEvtPos.y) > 5)){
            this.canvasInfo.status = statusConfig.DRAGGING;
            this.canvasInfo.offsetEvtPos = canvasPosition;
          }else if(this.canvasInfo.status === statusConfig.DRAGGING){
            let dragTarget = this.canvasInfo.dragTarget;
            dragTarget.x += (canvasPosition.x - this.canvasInfo.offsetEvtPos.x);
            dragTarget.y += (canvasPosition.y - this.canvasInfo.offsetEvtPos.y);
            this.render();
            this.canvasInfo.offsetEvtPos = canvasPosition;
          }
        });

        // 监听鼠标松开事件
        canvas.addEventListener('mouseup', () => {
          if(this.canvasInfo.status === statusConfig.DRAGGING){
            this.canvasInfo.status = statusConfig.IDLE;
          }
        });

        // 监听鼠标松开事件
        canvas.addEventListener('mouseout', (e) => {
          this.canvasInfo.status = statusConfig.IDLE;
          let canvasPosition = this.getCanvasPosition(e, this.canvasInfo.offset);
          this.canvasInfo.lastEvtPos = canvasPosition;
          this.canvasInfo.offsetEvtPos = canvasPosition;
        });

        // 监听鼠标滚轮事件
        canvas.addEventListener('wheel', (e) => {
          // e.preventDefault();
          let canvasPosition = this.getCanvasPosition(e, this.canvasInfo.offset);
          let deltaX = canvasPosition.x / this.canvasInfo.scale * this.canvasInfo.scaleStep;
          let deltaY = canvasPosition.y / this.canvasInfo.scale * this.canvasInfo.scaleStep;
          let scaleImgWidth = this.imgRef.width * this.canvasInfo.scale;
          let scaleImgHeight = this.imgRef.height * this.canvasInfo.scale;
          if(e.wheelDelta > 0 && this.canvasInfo.scale <= this.canvasInfo.maxScale){
            this.canvasInfo.offset.x -= deltaX;
            this.canvasInfo.offset.y -= deltaY;
            this.canvasInfo.scale += this.canvasInfo.scaleStep;
          }else{
            if (scaleImgWidth <= this.canvas.width || scaleImgHeight <= this.canvas.height) {
              return;
            }else{
              this.canvasInfo.offset.x += deltaX;
              this.canvasInfo.offset.y += deltaY;
              this.canvasInfo.scale -= this.canvasInfo.scaleStep;
              if (scaleImgWidth <= this.canvas.width || scaleImgHeight <= this.canvas.height) {
                // 达到限制条件，不再缩小
                  return;
              }
            }
          }
          this.render();
        });
      },
      closeDialog(){
        this.canvas = null;
        this.context = null;
        this.imgRef = null;
        this.visible = false;
        this.canvasInfo = {
          status: statusConfig.IDLE,
            dragTarget: {x:0,y:0,w:0,h:0},
          lastEvtPos: {x:null,y:null},
          offsetEvtPos: {x:null,y:null},
          offset: {x:0,y:0},
          scale: 1,
            scaleStep: 0.01,
            minScale: 0.5,
            maxScale: 2,
        };
      }
    },
  }
</script>

<style scoped>
  .previewClass{
    position:absolute;
    border-style:solid;
    border-color:red;
    opacity:0.3;
    z-index:3;
  }

  #myCanvas {
    display: block;
    margin: 0 auto; /* 水平居中 */
  }
  .parent{
    position: relative; /* 设置父元素的position为relative */
    background-color: white;
  }
  .blood {
    position: absolute; /* 设置相框的position为absolute */
    top: 50%; /* 距离父元素顶部50% */
    left: 50%; /* 距离父元素左侧50% */
    transform: translate(-50%, -50%) ; /* 将相框自身向左和向上移动50%，使其居中 */
    background-color: transparent; /* 设置相框背景为透明 */
    pointer-events:none;
  }
</style>
