<template>
  <div
    v-magnifier
    class="magaifier-wrapper"
    :style="{
      width: imgWidth + 'px',
      height: imgHeight + 'px',
    }"
  >
    <img
      :src="url"
      :alt="imgAlt"
      class="static-img"
      :style="{
        width: imgWidth + 'px',
        height: imgHeight + 'px',
      }"
    />
    <div
      class="mag-wra"
      :style="{
        width: magWidth + 'px',
        height: magHeight + 'px',
        borderRadius: magRadius + 'px',
      }"
    >
      <img
        :src="url"
        :alt="imgAlt"
        class="mag-img"
        :style="{
          width: imgWidth + 'px',
          height: imgHeight + 'px',
        }"
      />
    </div>
  </div>
</template>

<script>
import { reactive, toRefs } from "vue";
export default {
  name: "Magaifier",
  directives: {
    magnifier: {
      mounted(el) {
        /*
         *获取所需参数
         */
        const imgWar = el,
          magWra = el.querySelector(".mag-wra"),
          magImg = el.querySelector(".mag-img"),
          imgWidth = parseInt(window.getComputedStyle(imgWar, null)["width"]),
          imgHeight = parseInt(window.getComputedStyle(imgWar, null)["height"]),
          magWidth = parseInt(window.getComputedStyle(magWra, null)["width"]),
          magHeight = parseInt(window.getComputedStyle(magWra, null)["height"])
        let imgX = imgWar.offsetLeft
        let imgY = imgWar.offsetTop

        /*
         *入口函数
         */
        const init = () => {
          bindEvent()
        }

        /*
         *绑定事件处理函数
         */
        function bindEvent() {
          imgWar.addEventListener(
            "mouseover",
            function (e) {
              magWra.className += " show";
              document.addEventListener("mousemove", handleMouseMove, false)
            },
            false
          );
          imgWar.addEventListener("mouseout", handleMouseOut, false)
        }

        /*
         *鼠标移出动事件
         */
        function handleMouseMove(e) {
          const { x, y, mouseX, mouseY } = getXY(e)
          showMag(x, y, mouseX, mouseY)
        }

        /*
         *鼠标移出事件
         */
        function handleMouseOut() {
          magWra.className = "mag-wra"
          document.removeEventListener("mousemove", handleMouseMove, false)
        }

        /*
         *鼠标移动处理函数
         */
        function showMag(x, y, mouseX, mouseY) {
          magWra.style.left = x + "px"
          magWra.style.top = y + "px"
          magImg.style.left = -x + "px"
          magImg.style.top = -y + "px"
          if (
            mouseX < 0 ||
            mouseY < 0 ||
            mouseX > imgWidth ||
            mouseY > imgHeight
          ) {
            handleMouseOut()
          }
        }
        /*
         *获取坐标
         */
        function getXY(e) {
          let imgX = imgWar.getBoundingClientRect().x
          let imgY = imgWar.getBoundingClientRect().y
          return {
            x: e.clientX - imgX - magWidth / 2,
            y: e.clientY - imgY - magHeight / 2,
            mouseX: e.clientX - imgX,
            mouseY: e.clientY - imgY
          };
        }
        init()
      }
    }
  },
  props: {
    url: String,
    imgWidth: {
      type: String,
      default: "200"
    },
    imgHeight: {
      type: String,
      default: "300"
    },
    magWidth: {
      type: String,
      default: "100"
    },
    magHeight: {
      type: String,
      default: "100"
    },
    magRadius: {
      type: String,
      default: "0"
    },
    imgAlt: String
  }
}
</script>

<style lang="scss" scope>
.magaifier-wrapper {
  position: relative;
  box-sizing: border-box;
  .mag-wra {
    position: absolute;
    left: 0;
    top: 0;
    overflow: hidden;
    display: none;
    .mag-img {
      position: absolute;
      left: 0;
      top: 0;
      cursor: move;
    }
  }
  .show {
    display: block;
    transform: scale(1.5);
  }
}
</style>