记录--浏览器跨标签星球火了,简单探究一下实现原理

这篇具有很好参考价值的文章主要介绍了记录--浏览器跨标签星球火了,简单探究一下实现原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--浏览器跨标签星球火了,简单探究一下实现原理

一、前言

最近 推特上 一位懂设计和写代码的大神一个两个浏览器之间 星球粒子交互的动画火了, 让人看了大呼脑洞大开, 浏览器竟然还能这么玩!!!

准备自己也搞搞玩一下

记录--浏览器跨标签星球火了,简单探究一下实现原理

二、实现

原作者的粒子动画非常炫酷, 但是不是我们本文重点, 我们通过一个元素在不同窗口的拖拽实现一个可以变幻的例子来学习一下原理, 后续在实现一个稍微复杂的多窗口的小游戏。关于粒子动画的内容,有兴趣的小伙伴可以自己实现

其实实现类似的功能需要的难点并不多,不在乎以下几个步骤

  • 1、 屏幕坐标和窗口坐标转换
  • 2、 跨标签通讯

1、 先来看第一个点, 获取屏幕坐标与窗口坐标

// 屏幕坐标转换为窗口坐标
const screenToClient = (screenX, screenY) => {
  const clienX = screenX - window.screenX;
  const clienY = screenY - window.screenY - barHeight();
  return [clienX, clienY];
};

// 窗口坐标转换为屏幕坐标
const clientToScreen = (clienX, clienY) => {
  const screenX = clienX + window.screenX;
  const screenY = clienY + window.screenY + barHeight();
  return [screenX, screenY];
};

我们先简单实现一个卡片, 通过url上面传递颜色值, 设置定位

在卡片本上设置上点击拖动等事件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>跨标签通讯</title>
  </head>
  <style>
    .card {
      width: 300px;
      height: 300px;
      background-color: #f00;
      position: fixed;
      top: 100px;
      left: 100px;
    }
  </style>
  <body>
    跨标签通讯
    <div class="card">card</div>
  </body>
  <script>
    const barHeight = () => window.outerHeight - window.innerHeight;
    const cardDom = document.querySelector(".card");
    cardDom.style.top = 100 + "px";
    cardDom.style.left = 100 + "px";
    cardDom.style.background =
      new URLSearchParams(window.location.search).get("color") || "red";

    window.onload = function () {
      cardDom.onmousedown = function (e) {
        cardDom.style.cursor = "pointer";
        let x = e.pageX - cardDom.offsetLeft;
        let y = e.pageY - cardDom.offsetTop;
        window.onmousemove = function (e) {
          cardDom.style.left = e.clientX - x + "px";
          cardDom.style.top = e.clientY - y + "px";
          // 发送消息
          const clientCoordinateX = e.clientX - x;
          const clientCoordinateY = e.clientY - y;
          const ScreenCoordinate = clientToScreen(
            clientCoordinateX,
            clientCoordinateY
          );
          sendMessage(ScreenCoordinate);
        };
        window.onmouseup = function () {
          window.onmousemove = null;
          window.onmouseup = null;
          cardDom.style.cursor = "unset";
        };
      };
    };
  </script>
</html>

2、 跨标签传输

单个元素的拖动就实现了, 很简单, 如何让其他标签的元素也能同步进行, 需要实现跨标签方案了, 可以参考该文章- 跨标签页通信的8种方式

我们就选择第一种,使用 BroadCast Channel, 使用也很简单

// 创建 Broadcast Channel
const channel = new BroadcastChannel("myChannel");
// 监听消息
channel.onmessage = (event) => {
  // 处理接收到的消息
  console.log('接收',event)
};
// 发送消息
const sendMessage = (message) => {
  channel.postMessage(message);
};
只需要在移动时发送消息, 再其他标签页就可以接收到值了, 现在关键的就是收到发送的坐标点后, 如何处理, 其实关键就是要让几个窗口的卡片位置转化到同一个纬度, 让其再超出浏览器的时候,再另一个窗口的同一个位置出现, 所以就需要将窗口坐标转化成屏幕坐标,发送给其他窗口后, 再转化成窗口坐标进行渲染即可
// 鼠标移动发送消息的时候,窗口坐标转化成屏幕坐标
window.onmousemove = function (e) {
  cardDom.style.left = e.clientX - x + "px";
  cardDom.style.top = e.clientY - y + "px";
  const clientCoordinateX = e.clientX - x;
  const clientCoordinateY = e.clientY - y;
  const ScreenCoordinate = clientToScreen(
    clientCoordinateX,
    clientCoordinateY
  );
sendMessage(ScreenCoordinate);
  
// 接收消息的时候,屏幕坐标转化成窗口坐标 
channel.onmessage = (event) => {
  // 处理接收到的消息
  const [clienX, clienY] = screenToClient(...event.data);
  // 不同窗口的卡片要在同一个位置, 要放到同一个坐标系下面,保持屏幕坐标一致
  cardDom.style.left = clienX + "px";
  cardDom.style.top = clienY + "px";
};

完整代码,在最下面

三、总结

本文通过移动一个简单的图形, 在不同浏览器之间穿梭变换, 初步体验了多个浏览器之间如何进行交互, 通过拖拽元素,通过跨标签的通讯, 将当前窗口元素的位置进行发送, 另一个窗口进行实时接收, 然后通过屏幕坐标和窗口坐标进行转换, 就能实现,从一个浏览器拖动到另一个浏览器时, 变化元素颜色的功能了, 当然变化背景色只是举例子, 你也可以变化扑克牌, 变化照片, 这样看起来像变魔术一样,非常神奇,看似浏览器不同标签之间没有联系,当以这种方式产生联系后, 就会产生很多不可思议的神奇事情。 就像国外大神的多标签页的两个星球粒子, 产生吸引 融合的效果。原理其实是一样的。

后续前瞻

在通过小demo的学习,知道多浏览器的玩法后, 接下来的我们会实现一个更有意思的小游戏,通过浏览器化身一个小木棒, 接小球游戏, 先看一下 gif, 接下来的文章会写具体实现

记录--浏览器跨标签星球火了,简单探究一下实现原理

 

传送门 👇 多标签通讯--实现用浏览器接小球游戏

完整代码实现如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>跨标签通讯</title>
  </head>
  <style>
    .card {
      width: 300px;
      height: 300px;
      background-color: #f00;
      position: fixed;
      top: 100px;
      left: 100px;
    }
  </style>
  <body>
    跨标签通讯
    <div class="card">card</div>
  </body>
  <script>
    const barHeight = () => window.outerHeight - window.innerHeight;
    const cardDom = document.querySelector(".card");
    cardDom.style.top = 100 + "px";
    cardDom.style.left = 100 + "px";
    cardDom.style.background =
      new URLSearchParams(window.location.search).get("color") || "red";

    // 屏幕坐标转换为窗口坐标
    const screenToClient = (screenX, screenY) => {
      const clienX = screenX - window.screenX;
      const clienY = screenY - window.screenY - barHeight();
      return [clienX, clienY];
    };

    // 窗口坐标转换为屏幕坐标
    const clientToScreen = (clienX, clienY) => {
      const screenX = clienX + window.screenX;
      const screenY = clienY + window.screenY + barHeight();
      return [screenX, screenY];
    };

    // 创建 Broadcast Channel
    const channel = new BroadcastChannel("myChannel");
    // 监听消息
    channel.onmessage = (event) => {
      // 处理接收到的消息
      const [clienX, clienY] = screenToClient(...event.data);
      // 不同窗口的卡片要在同一个位置, 要放到同一个坐标系下面,保持屏幕坐标一致
      cardDom.style.left = clienX + "px";
      cardDom.style.top = clienY + "px";
    };

    // 发送消息
    const sendMessage = (message) => {
      channel.postMessage(message);
    };

    window.onload = function () {
      cardDom.onmousedown = function (e) {
        cardDom.style.cursor = "pointer";
        let x = e.pageX - cardDom.offsetLeft;
        let y = e.pageY - cardDom.offsetTop;
        window.onmousemove = function (e) {
          cardDom.style.left = e.clientX - x + "px";
          cardDom.style.top = e.clientY - y + "px";
          // 发送消息
          const clientCoordinateX = e.clientX - x;
          const clientCoordinateY = e.clientY - y;
          const ScreenCoordinate = clientToScreen(
            clientCoordinateX,
            clientCoordinateY
          );
          sendMessage(ScreenCoordinate);
        };
        window.onmouseup = function () {
          window.onmousemove = null;
          window.onmouseup = null;
          cardDom.style.cursor = "unset";
        };
      };
    };
  </script>
</html>

本文转载于:

https://juejin.cn/post/7304598711992598566

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--浏览器跨标签星球火了,简单探究一下实现原理文章来源地址https://www.toymoban.com/news/detail-747286.html

到了这里,关于记录--浏览器跨标签星球火了,简单探究一下实现原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 苹果safari浏览器播放不了video标签视频

    今天遇到了个神奇的问题,视频文件在pc端和安卓手机上播放都没问题,但是在ios上就是播放不了,大概代码如下: 前端代码: 后端代码: PC端没任何问题: IOS端播放不了: 在网上搜索了很多办法,有加前端参数配置的: 有改后端多次发送请求,分段获取数据流的: 经过

    2024年02月16日
    浏览(85)
  • JS监听浏览器关闭、刷新及切换标签页触发事件

    蛮简单的东西,知道就会,不知道就不会,没什么逻辑可言。简单记录一下,只为加深点儿印象。 visibilitychange visibilitychange可以监听到浏览器的切换标签页。  直接上代码:  beforeunload  beforeunload可以监听到页面的关闭,页签切换不会触发 关闭浏览器窗口的时候触发 通过点

    2024年02月08日
    浏览(54)
  • selenium基本使用、无头浏览器(chrome、FireFox)、搜索标签

    这个模块:既能发请求,又能解析,还能执行js selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行 JavaScript代码的问题 selenium 会做web方向的自动化测试 appnium 会做 app方向的自动化测试 selenium 可以操作浏览器,模拟人的 行为 下载浏览器驱动

    2024年02月04日
    浏览(69)
  • 前端:html实现页面切换、顶部标签栏,类似于浏览器的顶部标签栏(完整版)

    效果 代码 解决BUG:关闭单页时,单页数据未清空,导致再次打开单页时出现内容仍然存在的问题

    2024年02月11日
    浏览(53)
  • 实用工具推荐,浏览器必备宝藏插件:Wetab新标签页

    打开浏览器,你的起始页是否充满了广告和各种乱七八糟的信息呢?或者过于单调,而失去了某些你想要的功能? 这里给大家推荐一个在Chrome浏览器和edge浏览器上都能愉快使用的浏览器插件——Wetab新标签页。没有广告、页面干净美观且具备各种实用功能。   下面就给大家

    2024年02月08日
    浏览(49)
  • 谷歌chrome浏览器无法自动播放video标签视频的问题

    问题根源详见: Chrome中的自动播放政策  https://developer.chrome.com/blog/autoplay/  The Autoplay Policy launched in Chrome 66 for audio and video elements and is effectively blocking roughly half of unwanted media autoplays in Chrome. For the Web Audio API, the autoplay policy launched in Chrome 71. This affects web games, some WebRTC appli

    2024年02月11日
    浏览(99)
  • 如何处理html5新标签的浏览器兼容问题?

    处理HTML5新标签的浏览器兼容问题,特别是针对较旧的浏览器,可以采用以下几种方法: 使用JavaScript创建元素 : 对于不支持HTML5新标签的浏览器,可以使用JavaScript(特别是Document Object Model,DOM)来创建这些元素。例如,可以使用 document.createElement(\\\'article\\\') 来在DOM中创建 art

    2024年01月21日
    浏览(52)
  • vantUI(Tabbar标签页)浏览器返回上一页的失效问题

    在开发中遇到这样一个问题,由页面1切换到页面2,再点击浏览器的回退,无法回退到页面1。 开始以为是路由配置的有问题,但是子页面可以正常回退,因为replace只是替换路由,而不会往history栈中记录路由,所以当切换到页面2的时候,历史的路由里已经没有页面1了,所以

    2024年02月06日
    浏览(50)
  • 新版edge浏览器读取谷歌浏览器上的历史记录

    上一篇: (3条消息) 新版edge浏览器读取谷歌浏览器上的历史记录_learningbilibili的博客-CSDN博客 https://blog.csdn.net/learningbilibili/article/details/123662218 关于上次的读取历史记录的问题是现在的edge浏览器最近的版本更新后出现了每次启动时从 Google Chrome 导入浏览器数据的功能,而且是

    2024年02月09日
    浏览(66)
  • 如何在Firefox火狐浏览器点击链接打开新标签页、搜索、和书签

    打开Firefox火狐浏览器设置 在Firefox的地址栏输入 about:config 按回车键后,打开了一个警告页面,单击“接受风险并继续”即可,如下图所 在新标签页打开网页上的链接(点击链接打开新标签页) 在窗口中输入 browser.urlbar.openintab 双击显示的值更改为 true 在新标签中打开搜索结

    2024年02月05日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包