屏幕窗口和坐标通信

103 阅读1分钟
  1. 创建原始 html css js

  • 创建img文件夹
  • 创建index.js文件
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
   <style>
       body{
           margin: 0;
           padding: 0;
           box-sizing: border-box;
       }
       img{
           position: fixed;
           left: 0;
           top: 0;
           width: 200px;
           height: 300px;
       }
   </style>
</head>
<body>
   <script src="./index.js"></script>
</body>
</html>
  1. 构建初始化init函数

// 先创建img元素
const card = document.createElement('img');
document.body.appendChild(card);

(function init() {
    const url = new URL(window.location.href);
    const type = url.searchParams.get("type") || 'J'
    card.src = ./img/${type}.png
    card.onmousedown = (e) => {
        e.preventDefault() // 阻止图片默认事件
        // 1️⃣获取开始的图片位置
        let x = e.pageX - card.offsetLeft;
        let y = e.pageY - card.offsetTop;
        window.onmousemove = (e) => {
            const cx = e.pageX - x
            const cy = e.pageY - y
            // 2️⃣移动时修改
            card.style.left = cx + 'px';
            card.style.top = cy + 'px';
        }
        window.onmouseup = (e) => {
            // 3️⃣停止移动则清空事件
            window.onmousemove = null
            window.onmouseup = null
        }
    }
})();
  1. 创建辅助函数

    • 获取浏览器 bom 的高度
    • 将点击的视口坐标转换成屏幕坐标
    • 将屏幕坐标转换成视口坐标
// 获取浏览器BOM的高度
function getBarHeight() {
    // console.log(window.outerHeight, window.innerHeight);
    return window.outerHeight - window.innerHeight
}

// 将视口坐标转换成屏幕坐标
function clientToScreen(x, y) {
    // screenX和screenY属性返回窗口相对于屏幕的X和Y坐标。
    const screenx = x + window.screenX
    const screeny = y + window.screenY + getBarHeight()
    return [screenx, screeny]
}

// 将屏幕坐标转换成视口坐标
function screenToClient(x, y) {
    const clientX = x - window.screenX
    const clientY = y - window.screenY - getBarHeight()
    return [clientX, clientY]
}
  1. 创建 BroadcastChannel 广播频道对象

const channel = new BroadcastChannel("card");
channel.onmessage = (e) => {
    console.log(e.data);
    const clientPoints = screenToClient(...e.data);
    card.style.left = clientPoints[0] + 'px';
    card.style.top = clientPoints[1] + 'px';
}

(function init() {
    const url = new URL(window.location.href);
    const type = url.searchParams.get("type") || 'J'
    card.src = ./img/${type}.png
    card.onmousedown = (e) => {
        e.preventDefault()
        // 1️⃣获取开始的图片位置
        let x = e.pageX - card.offsetLeft;
        let y = e.pageY - card.offsetTop;
        window.onmousemove = (e) => {
            const cx = e.pageX - x
            const cy = e.pageY - y
            // 2️⃣移动时修改
            card.style.left = cx + 'px';
            card.style.top = cy + 'px';
            const screenPoints = clientToScreen(cx, cy)  //将视口坐标转换成屏幕坐标
            channel.postMessage(screenPoints)  //发送广播,其他窗口接收
        }
        window.onmouseup = (e) => {
            window.onmousemove = null
            window.onmouseup = null
        }
    }
})();