Javascript屏幕坐标与浏览器窗口通信:打造炫酷的扑克牌魔术

看短视频的时候,刷到一个很神奇的Javascrip效果,运用到的技术点包括了屏幕坐标的计算与浏览器窗口间通信。视频中代码已经给的很完整了,但没有具体的DEMO下载,按照教程,尝试着做了一下,效果还是很不错的。动图如下:
在这里插入图片描述
代码很简单,一共4张扑克牌图片,一个html、一个js和一个css文件。

html代码:

<!DOCTYPE html><html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <link rel="stylesheet" href="./index.css">
        <title>窗口通信</title>
    </head>
    <body>
        <img draggable="false" class="card">
        <script src="./index.js"></script>
    </body></html>

js文件

首先定义一个init方法,用来初始化扑克牌,通过接收url中的type参数,显示不同的扑克牌

const card = document.querySelector(".card");function init(){
    const url = new URL(window.location);
    const type = url.searchParams.get("type") || 'Q';
    card.src = `./${type}.png`;}init();

然后定义扑克牌的拖动

card.onmousedown = (e) => {
    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;
        card.style.left = cx + "px";
        card.style.top = cy + "px";
        const screenPoints = clientToScreen(cx, cy);
        channle.postMessage(screenPoints);
    };
    window.onmouseup = () => {
        window.onmousemove = null;
        window.onmouseup = null;
    };}

其他的就是用到的辅助方法

/**
 * 获取浏览器窗口的工具栏和地址栏高度
 *
 * @returns 浏览器窗口的工具栏和地址栏的高度值
 */function barHeight(){
   return window.outerHeight - window.innerHeight;}/**
 * 将客户端坐标转换为屏幕坐标
 *
 * @param x 客户端x坐标
 * @param y 客户端y坐标
 * @returns 返回屏幕坐标数组 [screenX, screenY]
 */function clientToScreen(x,y){
    const screenX = x + window.screenX;
    const screenY = y + window.screenY + barHeight();
    return [screenX, screenY];}/**
 * 将屏幕坐标转换为客户端坐标
 *
 * @param x 屏幕横坐标
 * @param y 屏幕纵坐标
 * @returns 转换后的客户端坐标数组 [clientX, clientY]
 */function screenToClient(x,y){
    const clientX = x - window.screenX;
    const clientY = y - window.screenY - barHeight();
    return [clientX, clientY];}const channle = new BroadcastChannel("card");channle.onmessage = (e) => {
    const clientPoints = screenToClient(...e.data);
    card.style.left = clientPoints[0] + "px";
    card.style.top = clientPoints[1] + "px";}

css代码

css很简单,定义图片的宽高和位置即可。

body{margin: 0;padding: 0;position: relative; width: 100%;height: 100%; overflow: hidden;}.card{width: 200px; height: auto;cursor: pointer;position: absolute;}

至此,全部代码就完成了。可以直接打开浏览器,也可以架设一个简单web服务来打开浏览器。输入相应的参数,如

http://localhost:8080/index.html?type=q

可以打开2个、3个和4个窗口,分别输入对于的url。先拖动下任意窗口的扑克牌,等待其他几个窗口的扑克牌消失,这时就可以开始你的表演了。

完整源码下载

扫描下方公众号卡片,关注我,回复1015 下载!

总结

暂无,下次再会!