<template>
  <div class="sliding-pictures">
    <div class="vimg">
      <canvas id="sliderBlock"></canvas>
      <canvas id="codeImg"></canvas>
    </div>
    <div class="slider">
      <div class="track" :class="{ pintuTrue: puzzle }">{{ tips }}</div>
      <div class="button el-icon-s-grid" @mousedown.prevent="drag"></div>
    </div>
    <div class="operation">
      <span title="关闭验证码" @click="close" class="el-icon-circle-close"></span>
      <span @click="init" class="el-icon-refresh-left" title="刷新验证码" ></span>
    </div>
  </div>
</template>
<script>
    export default {
        name: 'ImageDrag',
        props: {
            allowOffset:{
              type: Number,
              default: 5
            },
            src: {
                type: String,
                default: "code.png"
            },
            visible: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                tips: "拖动左边滑块完成上方拼图",
                //滑块x轴数据
                slider: {
                    mx: 0,
                    bx: 0
                },
                size:40,
                //拼图是否正确
                puzzle: false
            };
        },
        created() {
        },
        watch: {
            visible(e) {
                if (e === true) {
                    this.puzzle = false;
                    this.init();
                }
            }
        },
        computed:{
        },
        methods: {
            success(){
                this.$emit("success",true);
            },
            init() {
                //生成指定区间的随机数
                const random = (min, max) => {
                    return Math.floor(Math.random() * (max - min + 1) + min);
                };
                //x: 254, y: 109
                let mx = random(50, 200),//高位数据
                    // bx = random(10, 128),//低位数据
                    y = random(10, 99);
                this.slider = {mx:mx,bx:20};
                this.draw(mx, 20, y);
            },
            //鼠标按下
            drag(e) {
                let dom = e.target; //dom元素
                let slider = document.querySelector("#sliderBlock"); //滑块dom
                const downCoordinate = {x: e.x, y: e.y};
                //正确的滑块数据
                let checkx = Number(this.slider.mx) - Number(this.slider.bx)-this.size/2;
                //x轴数据
                let x = 0;
                const move = moveEV => {
                    x = moveEV.x - downCoordinate.x;
                    if (x >= 251 || x <= 0) return false;
                    dom.style.left =  x+ "px";
                    slider.style.left = (x-checkx) + "px";
                };
                const up = () => {
                    document.removeEventListener("mousemove", move);
                    document.removeEventListener("mouseup", up);
                    dom.style.left = "";
                    // console.log("位置：",x,"偏移量："+ checkx);
                    let max = checkx + this.allowOffset;
                    let min = checkx - this.allowOffset;
                    //允许正负误差1
                  this.$core.debug().log("滑动解锁结果：当前位置",x,"要求区间",min,max);
                  if ((max >= x && x >= min) || x === checkx) {
                        this.puzzle = true;
                        this.tips = "验证成功";
                        setTimeout(() => {
                            this.success();
                            // this.visible = false;
                        }, 500);
                    } else {
                        this.tips = "验证失败，请重试";
                        this.puzzle = false;
                        this.init();
                    }
                };
                document.addEventListener("mousemove", move);
                document.addEventListener("mouseup", up);
            },
            draw(mx = 200, bx = 20, y = 50) {
                let mainDom = document.querySelector("#codeImg");
                let bg = mainDom.getContext("2d");
                let width = mainDom.width;
                let height = mainDom.height;
                let blockDom = document.querySelector("#sliderBlock");
                let block = blockDom.getContext("2d");
                //重新赋值，让canvas进行重新绘制
                blockDom.height = height;
                mainDom.height = height;
                let img = document.createElement("img");
                img.style.objectFit = "scale-down";
                img.src = this.$core.adapterUrl(this.src,this.$store.state.api.axios.baseURL);
                img.onload = function () {
                    bg.drawImage(img, 0, 0, width, height);
                    block.drawImage(img, 0, 0, width, height);//
                };
                let mainxy = {x: mx, y: y, r: 9};
                // let blockxy = {x: mx, y: y, r: 9};
                this.drawBlock(bg, mainxy, "fill");  //绘制填充区域
                this.drawBlock(block, mainxy, "clip");//绘制挖走的滑块
                //确定滑块位置
                let slider = document.querySelector("#sliderBlock"); //滑块dom
                let checkx = Number(this.slider.mx) - Number(this.slider.bx)-this.size/2;
                slider.style.left = (0-checkx)+ "px";
            },
            //绘制拼图
            drawBlock(ctx, xy = {x: 254, y: 109, r: 9}, type) {
                let x = xy.x,
                    y = xy.y,
                    r = xy.r,
                    w = this.size;
                let PI = Math.PI;
                //绘制
                ctx.beginPath();
                //left
                ctx.moveTo(x, y);
                //top
                ctx.arc(x + (w + 5) / 2, y, r, -PI, 0, true);
                ctx.lineTo(x + w + 5, y);
                //right
                ctx.arc(x + w + 5, y + w / 2, r, 1.5 * PI, 0.5 * PI, false);
                ctx.lineTo(x + w + 5, y + w);
                //bottom
                ctx.arc(x + (w + 5) / 2, y + w, r, 0, PI, false);
                ctx.lineTo(x, y + w);
                ctx.arc(x, y + w / 2, r, 0.5 * PI, 1.5 * PI, true);
                ctx.lineTo(x, y);
                //修饰，没有会看不出效果
                ctx.lineWidth = 1;
                ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
                ctx.strokeStyle = "rgba(255, 255, 255, 0.5)";
                ctx.stroke();
                ctx[type]();
                ctx.globalCompositeOperation = "xor";
            },close(){
              this.$emit("close",true);
          }
        }
    };
</script>

<style scoped lang="scss">
  /*该样式最终是以弹窗插入*/
  .sliding-pictures {
    padding: 0;
    width: 240px;
    height: 260px;
    border-radius: 2px;
    .vimg {
      width: 100%;
      height: calc(100% - 80px);
      #codeImg,#sliderBlock {
        padding: 3px 3px 0 3px;
        width: inherit;
        height: 100%;
      }
      #codeImg {

      }

      #sliderBlock {
        height: calc(100% - 104px);
        position: absolute;
        z-index: 4000;
      }
    }

    .slider {
      width: 100%;
      height: 65px;
      border-bottom: #c7c9d0 1px solid;
      display: flex;
      align-items: center;
      justify-content: flex-start;

      .track {
        margin-left: 7px;
        width: 286px;
        height: 38px;
        background: rgba(28, 136, 188, 0.5);
        border-radius: 25px;
        font-size: 12px;
        line-height: 38px;
        padding-right: 15px;
        padding-left: 70px;
      }

      .pintuTrue {
        background: #67c23a;
        color: #ffffff;
      }

      .button {
        position: absolute;
        width: 50px;
        height: 50px;
        line-height: 48px;
        background: #ffffff;
        box-shadow: #b9bdc8 0 0 3px;
        border-radius: 50%;
        left: 7px;
        text-align: center;
        font-size: 28px;
        color: #3e5d8b;

        &:hover {
          color: #2181bd;
        }
      }
    }
  }
</style>
