window.requestAnimationFrame+localStorage+canvas实现跨窗口小球连线效果

简介: window.requestAnimationFrame+localStorage+canvas实现跨窗口小球连线效果

前言

hello world欢迎来到前端的新世界


😜当前文章系列专栏:前端系列文章

🐱‍👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹

💖感谢大家支持!您的观看就是作者创作的动力

效果

小球连接效果

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div id="alert1" style="white-space:pre-wrap;"></div>
    <div id="alert2" style="white-space:pre-wrap;"></div>
    <canvas id="canvas1" style="position:absolute;left:0;top:0;"></canvas>
    <script src="./index.js"></script>
</body>
</html>
html{
    width: 100vw;
    height: 100vh;
}
body{
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
const alert1 = document.getElementById('alert1');
const alert2 = document.getElementById('alert2');
const canvas1 = document.getElementById('canvas1');
const ctx = canvas1.getContext('2d');
const keys = getOtherKeys(); // 获取其它窗口的keys
const key = keys.length == 0 ? 1 : keys.at(-1) + 1; // 自增最大的key序号,定义自己窗口storage key
const color = ['red', 'blue',"green"][key % 3]; // 获取圆颜色
// 窗口关闭时删除自己窗口storage
window.onunload = function () {
    localStorage.removeItem(key);
}
function getOtherKeys() {
    const keys = [];
    for (let i = 0; i < localStorage.length; i++) {
        const k = Number(localStorage.key(i));
        !isNaN(k) && keys.push(k);
    }
    return keys.sort((a, b) => a - b);
}
function draw() {
    const { clientWidth, clientHeight } = document.body; // 获取body高宽
    const { screenX, screenY } = window; // 获取浏览器相对屏幕坐标
    const barHeight = window.outerHeight - window.innerHeight; // 获取浏览器body顶部地址栏高度
    // 设置canvas为整个body高宽,铺满body
    canvas1.width = clientWidth;
    canvas1.height = clientHeight;
    // 获取自己的圆心坐标,为body中心
    const x = clientWidth / 2;
    const y = clientHeight / 2;
    // 画自己的圆
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.arc(x, y, 15, 0, Math.PI * 2);
    ctx.fill();
    // 记录自己的position
    const position = {
        top: y + barHeight + screenY,
        left: x + screenX,
        color: color,
    };
    // 获取其它窗口position,并遍历
    getOtherKeys().forEach(k => {
        const position2 = JSON.parse(localStorage.getItem(k)); // 获取其中一个窗口的圆心position
        const w = position2.left - position.left; // 获取相对自己圆心的横向间距
        const h = position2.top - position.top; // 获取相对自己圆心的纵向间距
        // 在自己的canvas上画出该圆
        ctx.fillStyle = position2.color;
        ctx.beginPath();
        ctx.arc(x + w, y + h, 15, 0, Math.PI * 2);
        ctx.fill();
        // 画连接线
        ctx.strokeStyle = "black";
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x + w, y + h);
        ctx.stroke();
    })
    // 更新自己窗口的position
    localStorage.setItem(key, JSON.stringify(position));
    window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);

后言

创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力


目录
相关文章
|
NoSQL Linux Redis
Docker安装Redis并配置文件启动
之前已经写过Redis分别在Linux、Windows上安装部署,及其集群环境搭建。这次写一篇Docker容器部署Redis的教程,配置文件方式启动服务。
Docker安装Redis并配置文件启动
|
8月前
|
人工智能 自然语言处理 测试技术
URO-Bench:端到端语音对话模型评测黑马!多语言/多轮/副语言全维度一键开测
URO-Bench 是一款专为端到端语音对话模型设计的全面基准测试工具,涵盖多语言、多轮对话、副语言信息等多维度任务,帮助开发者全面评估模型性能。
588 1
|
7月前
|
安全 前端开发 Android开发
拥抱国产化:转转APP的鸿蒙NEXT端开发尝鲜之旅
本文将要分享的是转转APP在开发全新鸿蒙NEXT端所遇到的一些问题,对比了鸿蒙开发和 Android、iOS 的不同,总结了这次开发过程中的一些经验等等。希望能带给你启发。
224 0
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
147 3
|
算法 安全 API
淘宝获得淘口令真实URL接口的技术解析
淘口令是淘宝的加密链接,用于商品推广。官方未提供直接解密API,但第三方工具或API能模拟解析。示例代码展示了如何通过第三方接口(需替换为真实接口)获取淘口令所对应的URL、标题和图片信息,但使用时需注意安全风险。
731 2
|
容器
实时数仓Hologres构建环境问题之Dockerfile描述如何解决
在制品构建时明确依赖版本可避免因版本变动引起的构建差异,确保一致性与可预测性。通过Dockerfile指定确切版本的依赖与环境,能够跨平台重现相同的构建环境。为保证构建脚本一致性,应采用与业务代码解耦的构建脚本,并严格控制环境变量。构建准确性和速度都很重要,但通常准确性优先,确保制品质量稳定可靠。
133 0
|
小程序 程序员
探索代码之美:我的编程旅程
【6月更文挑战第13天】本文将通过个人经历和感悟,探讨编程不仅仅是一项技能,更是一种艺术。从最初的迷茫到现在的热爱,作者分享了自己在编程世界中的探索过程,以及如何逐渐发现代码背后的美学和逻辑。
|
Java 测试技术 Maven
博客系统实现自动化测试
博客系统实现自动化测试
129 1