使用 jquery 和 canvas 从 html 元素 id 到另一个 html 元素绘制线条

2024-01-04

html和jquery是否可以只通过引用元素id来画一条线?我在文本中有一个重要的单词,并且想在该单词和描述它的图像之间画一条线。我已经看到可以使用画布在元素之间进行绘制,但它们的样式位置设置为绝对。由于我的元素是文本中的单词,因此我无法将其设置为绝对。 例子

<p>This is my text with this very <span id="important_word">important</span> word</p>
...
<img src="important.jpg" id="important_img"/>

现在我想在跨度和图像之间画一条线。是否可以?

提前致谢!


由于这个问题时不时地出现,我已经付出了一些努力。它不是jquery,所以你可能可以在某种程度上简化。仅供参考,这个答案也发布在另一个问题的答案 https://stackoverflow.com/questions/22615338/drawing-lines-between-2-elements-onclick/22662087#22662087,但要求是一样的。使用该问题的html和CSS,这里有一个jsbin演示 http://jsbin.com/guken/3/http://jsbin.com/guken/3/ http://jsbin.com/guken/3/

该方法是创建一个浮动画布元素(粉红色阴影),并将其放置在 DOM 其余部分的下方(使用 z-index)。然后,我计算两个框边界上与框中心之间的线相对应的点。红色和蓝色方块实际上是随行端移动的 div,可用于注释,如源、目标等。

在该 jsbin 中,您可以单击一个元素,然后准备一行以单击下一个元素。它会检测所选元素的悬停,并在将鼠标悬停在其中一个元素上时捕捉到目标。

我不会在此处粘贴所有代码,但我们在客户端 DOM 坐标中从一个 x,y 位置到另一个位置绘制一条线的部分是这样的:

var lineElem;
function drawLineXY(fromXY, toXY) {
    if(!lineElem) {
        lineElem = document.createElement('canvas');
        lineElem.style.position = "absolute";
        lineElem.style.zIndex = -100;
        document.body.appendChild(lineElem);
    }
    var leftpoint, rightpoint;
    if(fromXY.x < toXY.x) {
      leftpoint = fromXY;
      rightpoint = toXY;
    } else {
      leftpoint = toXY;
      rightpoint = fromXY;
    }

    var lineWidthPix = 4;
    var gutterPix = 10;
    var origin = {x:leftpoint.x-gutterPix, 
                  y:Math.min(fromXY.y, toXY.y)-gutterPix};
    lineElem.width = Math.max(rightpoint.x - leftpoint.x, lineWidthPix) + 
      2.0*gutterPix;
    lineElem.height = Math.abs(fromXY.y - toXY.y) + 2.0*gutterPix;
    lineElem.style.left = origin.x;
    lineElem.style.top = origin.y;
    var ctx = lineElem.getContext('2d');
    // Use the identity matrix while clearing the canvas
    ctx.save();
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, lineElem.width, lineElem.height);
    ctx.restore();
    ctx.lineWidth = 4;
    ctx.strokeStyle = '#09f';
    ctx.beginPath();
    ctx.moveTo(fromXY.x - origin.x, fromXY.y - origin.y);
    ctx.lineTo(toXY.x - origin.x, toXY.y - origin.y);
    ctx.stroke();
}

由于示例只有一行,并且我们始终可以存储已“完成”的行以准备创建更多行,因此它使用全局变量lineElem。第一次尝试绘制线条时,它会创建一个 canvas 元素,将其插入到 DOM 中并将其分配给 lineElem。在此构造之后,它随后重用画布元素,更改大小并重新绘制新的坐标对。

为了防止线条被画布边缘切断,有一个装订线设置可以填充画布的宽度和高度。剩下的就是在客户端 DOM 坐标和在画布本身上绘制的坐标之间进行正确的坐标转换。

唯一不直接的一点是沿着一条线计算框边界上的点的坐标。它并不完美,但这是一个合理的开始。关键是计算目标的角度(to)从源的角度来看(from)点,看看它与已知的盒子角角度相比如何:

function getNearestPointOutside(from, to, boxSize) {
    // which side does it hit? 
    // get the angle of to from from.
    var theta = Math.atan2(boxSize.y, boxSize.x);
    var phi = Math.atan2(to.y - from.y, to.x - from.x);
    var nearestPoint = {};
    if(Math.abs(phi) < theta) { // crosses +x
        nearestPoint.x = from.x + boxSize.x/2.0;
        nearestPoint.y = from.y + ((to.x === from.x) ? from.y : 
        ((to.y - from.y)/(to.x - from.x) * boxSize.x/2.0));
    } else if(Math.PI-Math.abs(phi) < theta) { // crosses -x
        nearestPoint.x = from.x - boxSize.x/2.0;
        nearestPoint.y = from.y + ((to.x === from.x) ? from.y : 
        (-(to.y - from.y)/(to.x - from.x) * boxSize.x/2.0));
    } else if(to.y > from.y) { // crosses +y
        nearestPoint.y = from.y + boxSize.y/2.0;
        nearestPoint.x = from.x + ((to.y === from.y) ? 0 : 
        ((to.x - from.x)/(to.y - from.y) * boxSize.y/2.0));
    } else { // crosses -y
        nearestPoint.y = from.y - boxSize.y/2.0;
        nearestPoint.x = from.x - ((to.y === from.y) ? 0 :
        ((to.x - from.x)/(to.y - from.y) * boxSize.y/2.0));
    }
    return nearestPoint;
}

Theta 是到第一个盒子角的角度,phi 是实际的线角度。

要获取客户端坐标中框的位置,您需要使用elem.getBoundingClientRect(),它产生左、上、宽、高等,我用它来找到盒子的中心:

function getCentreOfElement(el) {
    var bounds = el.getBoundingClientRect();
    return {x:bounds.left + bounds.width/2.0,
            y:bounds.top + bounds.height/2.0};
}

将所有这些放在一起,您可以从一个元素到另一个元素绘制一条线。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 jquery 和 canvas 从 html 元素 id 到另一个 html 元素绘制线条 的相关文章

  • HTML 中部分着色的阿拉伯语单词

    我不会说阿拉伯语 但我需要我们网站上对阿拉伯语的具体支持 我需要将部分阿拉伯语单词放在 span 与单词其他部分的风格不同 当我输入两个字符时 and 它们被组合成word 但是当我使用 HTML 标记时 span span 这些字母在输出
  • 在 webpack 2.x 中使用 autoprefixer 和 postcss

    如何使用autoprefixer使用 webpack 2 x 以前 它曾经是这样的 module loaders test scss loader style css sass postcss postcss gt return autop
  • 通过 CDN 使用 Dojo 时如何加载自定义 AMD 模块?

    我正在使用 google 的 CDN 并尝试使用他们的加载程序加载我自己的 AMD 模块 我知道我做错了什么 但我被困住了 有任何想法吗
  • Babel 7 Jest Core JS“TypeError:wks不是函数”

    将我的项目升级到 Babel 7 后 通过 Jest 运行测试会抛出以下错误 测试在 Babel 6 中运行没有任何问题 但在 Babel 7 中失败并出现以下错误 TypeError wks is not a function at Ob
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • Electron - 为什么在关闭事件时将 BrowserWindow 实例设置为 null

    The 电子文档 https electronjs org docs api browser window 提供以下代码示例来创建新窗口 const BrowserWindow require electron let win new Br
  • 如何使用 JQuery 动态排序

    如果我有一个下拉列表和一个列表框 有没有办法使用 JQuery 根据下拉列表对列表框进行排序 举个例子会很有帮助 这会改变下拉菜单中的顺序 您必须根据自己的标准设置顺序
  • Python GTK+ 画布

    我目前正在通过 PyGobject 学习 GTK 需要画布之类的东西 我已经搜索了文档 发现两个小部件似乎可以完成这项工作 GtkDrawingArea 和 GtkLayout 我需要一些基本函数 如 fillrect 或 drawline
  • 使用 JQuery 更改元素的顺序

    有人知道我做错了什么吗 我正在尝试更改某些图像的显示顺序 我希望每次按下按钮时图像都会向右 向左移动一个位置 这是我尝试过的 但没有运气 任何帮助或见解将不胜感激 rightShift click function img hide var
  • 如何判断 jquery 对话框是否打开? [复制]

    这个问题在这里已经有答案了 寻找通用案例解决方案来确定当前是否打开任何 jquery 对话框 有多个 试过 ui dialog content dialog isOpen true ui dialog dialog isOpen true
  • jQuery 获取元素内的鼠标位置

    我希望制作一个控件 用户可以在 div 内单击 然后拖动鼠标 然后松开鼠标以指示他们想要的内容有多长 这是针对日历控件的 因此用户将指示特定事件的时间长度 看起来最好的方法是在父 div 上注册一个 mousedown 事件 而父 div
  • 如何在没有@import的情况下减少@import?

    我用的较少 从 Google PageSpeed 我了解到 使用 importCSS 文件中的内容会影响网站速度 所以我想排除任何 import来自我的 CSS 的东西 我有 2 个不同的样式表reset css and rebuild c
  • 模块构建失败(来自 ./node_modules/babel-loader/lib/index.js)Vue Js

    我从 GitHub 下载了一个我和我的朋友正在开发的项目 但是当我尝试运行时 npm run serve 我收到这个错误 src main js 中的错误 Module build failed from node modules babe
  • 为什么我不能在 AngularJS 中使用 data-* 作为指令的属性名称?

    On the t他的笨蛋 http plnkr co edit l3KoY3 p preview您可以注意到属性名称模式的奇怪行为data 在指令中 电话 Test of data named attribute br
  • 有没有办法阻止 prettier / prettier-now 将函数参数分解为新行

    当使用 prettier prettier now 在保存时进行格式化时 当一个函数包装另一个函数时 它会中断到一个新行 我想知道是否有办法阻止这种行为 例如 期望的输出 app get campgrounds id catchAsync
  • Jquery 验证不能正确验证数字?

    我在使用 jquery 非侵入式验证验证数字时遇到问题 我使用的版本是 ASP NET MVC 3 jQuery 1 9 1 jQuery 用户界面 1 10 1 JQuery 验证 1 11 0 我试图验证的输入是
  • Safari 支持 JavaScript window.onerror 吗?

    我有一个附加到 window onerror 的函数 window onerror function errorMsg url line window alert asdf 这在 firefox chrome 和 IE 中工作正常 但在 s
  • 更改文本输入标签中文本的大小?

    我有一个很大的文本输入框 但我无法更改字体大小
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • jQuery 对象相等

    如何确定两个 jQuery 对象是否相等 我希望能够在数组中搜索特定的 jQuery 对象 inArray jqobj my array 1 alert deviceTypeRoot deviceTypeRoot False alert d

随机推荐

  • 由于 Dart 中的类型,该参数不能具有“null”值

    飞镖功能 我有以下 Dart 函数 并且现在使用空安全 void calculate int factor 分析仪抱怨说 由于其类型 参数 factor 不能具有 null 值 并且未提供非空默认值 颤动小部件 我的情况也是如此Statel
  • Java TCP 如何读取发送的流大小(标头)并根据该大小继续读取

    给出以下伪代码 我将如何读取给定的数据 Use 数据输入流 http docs oracle com javase 7 docs api java io DataInputStream html让您的生活变得轻松 DataInputStre
  • PHP邮件:所有电子邮件都会在SPAM文件夹中收到[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在制作一个简单的 PHP 邮件发
  • 如何在 Silverlight 5 中使用 VisualStateManager 重用 Storyboard

    这个问题以前曾被问过 但在大多数情况下不超过 2 年前 并且通常特定于 WPF 答案可能还是一样 但就这样了 我正在尝试构建一个三角形 箭头 按钮 当鼠标悬停在其上方时 该按钮会改变颜色并增大尺寸 我已经用一个按钮实现了这一点 但现在我需要
  • 如何在android视频视图中播放某个URL位置的视频?

    我试图在视频视图中播放 youtube 视频 但始终出现错误 无法播放此视频 在设备上以及模拟器上 请帮我解决这个问题 提前致谢 import android app Activity import android net Uri impo
  • body2 已弃用,不应使用。这是 2014 年版材料设计中使用的术语。 - 颤振中的警告消息

    如果您从版本更新flutter SDKv1 12 13之后的任何版本v1 13 8 您将收到几条与 textTheme 使用相关的警告消息 例如 下面给出其中之一 信息 body2 已弃用 不应使用 这是 2014 年版材料设计中使用的术语
  • 如何将哈希转换为 JSON,且转换后的字符串不包含反斜杠

    我正在使用将哈希值转换为 JSONto json 但转换后的字符串充满了反斜杠 如果我使用puts 它显示正确的字符串 但如果我传入一个HTTP NET request body 字符串中充满了反斜杠 data a gt b c gt d
  • 从 CSV 数据流 python 创建字典

    我正在尝试从 python 中的 csv 数据创建一个字典 我不想使用传统的 split 然后使用将行重命名为我想要的标题 因为我将收到具有不同格式的不同 csv 文件信息量很大 而且我将无法使用该方法一致地定位我想要的行 标头名称将是一致
  • Drupal 从 Twitter 导入推文作为节点

    我希望能够将我的推文作为 Nndes 从 twitter 导入到 Drupal 中 我希望能够链接 names and tags返回正确的页面 我也不希望 myTweeterName 出现在推文的开头 你会怎样做呢 twitter 模块不创
  • 使用 javascript 计算日期与开始日期和天数

    我正在尝试根据开始日期和天数计算日期 因此基本上将天数添加到开始日期并获取结束日期 问题是我得到了一些奇怪的结果 但只有一次约会 我已经花了几天时间试图弄清楚这个结果 其功能是 CallculateDateFromDays function
  • 如何使表格水平滚动并固定第一列和最后一列

    我下面有这张表 我希望它可以滚动 水平方向 但我想要表格的第一列和最后一列 是固定的 而中间的列是可滚动的 关于如何做的任何想法 来完成这个 我想在没有任何插件的情况下执行此操作 JavaScript 我的 css 位于 html 之后 谢
  • 适用于 iOS (xcode) 的 LZMA SDK 解压缩使用过多 RAM

    我正在尝试在 iPhone iPad 应用程序中使用 LZMA SDK 我的起点是 Mo Dejong 提供的 iPhone 的 LZMA 示例项目 可在此处获取 https github com jk lzmaSDK https gith
  • Clojure 的“core.logic”中的目标排序

    以下 Clojure 代码 https gist github com 4525736 uses core logic以两种不同的顺序解决具有相同目标的相同逻辑问题 这种排序选择会导致一个很快完成 另一个则挂起 use clojure co
  • 格式化 Carbon 日期实例

    我有一个返回以下日期时间的数组 item created at gt 2015 10 28 19 18 44 如何将日期更改为M d Y在 Laravel 中使用 Carbon 格式化 目前它返回错误 suborder payment da
  • 使用 Logback SizeAndTimeBasedFNATP 时如何限制每天的文件数量

    使用Logback SizeAndTimeBasedFNATP触发策略时 如何限制每天的文件数量 例如 在任何一天 我都不希望拥有超过 100MB 的日志 鉴于每个日志 在下面的示例中 为 20MB 我希望能够将每天的最大限制设置为 5 个
  • 如何在下拉列表中选择完整的日历月份和年份

    我有一个完整的日历 我需要在下拉列表中显示它的月份和年份 我知道这个问题已经被问过 但仍然没有得到解答 我是完整日历的新手 据我所知 它现在已更新 希望有一些最简单的方法来实现 而不是给它 gotodate 选项 我已经为日历创建了代码笔
  • 在 WebForms 应用程序中验证AntiForgeryToken

    我已经阅读了一些有关使用的内容ValidateAntiForgeryToken防止 XSRF CSRF 攻击 然而我所看到的似乎只与 MVC 有关 这些是我看过的文章 ValidateAntiForgeryToken 目的 解释和示例 ht
  • 禁用整个页面的 UpdateProgress

    我已经检查过这个解决方案 有没有办法禁用某些异步回发的 UpdateProgress https stackoverflow com questions 6299072 is there a way to disable updatepro
  • Jenkins 工作流程:如何获取或设置步骤 ID

    我们想引用 Jenkins 工作流程并行任务中的一个步骤 但似乎对于多个并行任务中的步骤创建的步骤 ID 是不确定的 对于输入步骤 可以手动指定步骤 ID 是否可以为 shell 步骤指定步骤 id 或查询步骤 id 目的是我们希望在并行任
  • 使用 jquery 和 canvas 从 html 元素 id 到另一个 html 元素绘制线条

    html和jquery是否可以只通过引用元素id来画一条线 我在文本中有一个重要的单词 并且想在该单词和描述它的图像之间画一条线 我已经看到可以使用画布在元素之间进行绘制 但它们的样式位置设置为绝对 由于我的元素是文本中的单词 因此我无法将