屏幕坐标&窗口通信

127 阅读1分钟

屏幕坐标&窗口通信

1. 拖动元素

<template lang="">
  <div class="cardImg">
    <img id="imgCard" :src="imgSrc" />
  </div>
</template>
<script>
export default {
/*省略*/
methods: {
     CardInit() {
      const url = new URL(window.location.href);
      const type = url.searchParams.get("type") || "12";
      this.imgSrc = require(`@/assets/ikun${type}.jpg`);
      const imgDom = document.querySelector(".cardImg");
      imgDom.onmousedown = (e) => {
        let x = e.pageX - imgDom.offsetLeft;
        let y = e.pageY - imgDom.offsetTop;
        window.onmousemove = (e) => {
          const cx = e.pageX - x;
          const cy = e.pageY - y;
          imgDom.style.left = cx + "px";
          imgDom.style.top = cy + "px";
        };
        window.onmouseup = () => {
          window.onmousemove = null;
          window.onmouseup = null;
        };
      };
    },
   },
};
</script>

2. 视口坐标与屏幕坐标的转化

浏览器窗口距离屏幕最上部分的高度,需要加上地址栏,标签页等一些的高度

    // 1. 获取那个浏览器上半部分的宽度(地址栏,标签页等高度)
    getBarHeight() {
        // 浏览器整个高度 - 浏览器窗口的高度 = [地址栏,标签页等高度]
      return window.outerHeight - window.innerHeight;
    },

    // 2. 视口坐标与屏幕坐标的转化

    clientToScreen(x, y) {
      const screenX = x + window.screenX;

      // 此时的y是视口坐标,需要加上屏幕坐标,加上地址栏,标签页等的高度
      const screenY = y + window.screenY + this.getBarHeight();
      return [screenX, screenY];
    },
    // 3. 视口坐标与屏幕坐标的转化
    screenToClient(x, y) {
      const clientX = x - window.screenX;
      const clientY = y - window.screenY - this.getBarHeight();
      return [clientX, clientY];
    },

3. 窗口通信与设置元素的位置

  • 由于是在同一个页面
const channel = new BroadcastChannel("ikun")  // 创建一个名为"ikun"的广播通道
  • 拖动页面1图片,通知其他页面的元素的位置发生改变
    上全部代码:

  methods: {
    CardInit() {
      const url = new URL(window.location.href);
      const type = url.searchParams.get("type") || "12";
      this.imgSrc = require(`@/assets/ikun${type}.jpg`);
      const imgDom = document.querySelector(".cardImg");
      imgDom.onmousedown = (e) => {
        let x = e.pageX - imgDom.offsetLeft;
        let y = e.pageY - imgDom.offsetTop;
        window.onmousemove = (e) => {
          const cx = e.pageX - x;
          const cy = e.pageY - y;
          imgDom.style.left = cx + "px";
          imgDom.style.top = cy + "px";

          // 5. 通过广播通道发送 位置
          const screenPoints = this.clientToScreen(cx,cy)
          channel.postMessage(screenPoints)

        };
        window.onmouseup = () => {
          window.onmousemove = null;
          window.onmouseup = null;
        };
      };
      this.dragElement()
    },

    // 1. 获取那个浏览器上半部分的宽度(地址栏,标签页等高度)

    getBarHeight() {
      return window.outerHeight - window.innerHeight;
    },

    // 2. 视口坐标与屏幕坐标的转化

    clientToScreen(x, y) {
      const screenX = x + window.screenX;

      // 此时的y是视口坐标,需要加上屏幕坐标,但是由于浏览器有一个地址栏,标签页的高度
      const screenY = y + window.screenY + this.getBarHeight();
      return [screenX, screenY];
    },
    // 3. 视口坐标与屏幕坐标的转化
    screenToClient(x, y) {
      const clientX = x - window.screenX;
      const clientY = y - window.screenY - this.getBarHeight();
      return [clientX, clientY];
    },


    // 4. 拖动元素--> 通知其他窗口,将元素视口位置设置到拖动元素最后移动的位置
    dragElement() {
      channel.onmessage = (e) => {
        const clientPoints = this.screenToClient(...e.data)
        const imgDom = document.querySelector(".cardImg");
        imgDom.style.left = clientPoints[0] + "px";
        imgDom.style.top = clientPoints[1] + "px";
      }
    }

  },
  • 效果展示

1.png 短视频看到的,写下来作为记录,大佬见谅。