将文本绕成 svg 或 canvas 中的圆形

2023-12-31

将文本适合网站上的圆圈,使其随圆圈的曲线流动而不是矩形边界框的一个好的解决方案是什么?

这就是我想要实现的目标: 页面上有许多黑色圆圈(固定大小),每个圆圈旁边都有一个文本区域。 当文本输入到文本区域时,它会出现在黑色圆圈中,以两个轴为中心。 如果输入的文本太多,以致线条变得比圆的半径长,减去指定的边距值,则线条将像您期望的常规换行一样断开,而文本块仍居中。 当然,靠近顶部或底部的线会比靠近中间的线短。

文本将具有固定的大小,当圆圈充满文本时,不应显示额外的内容(例如溢出隐藏)。

带有文字的黑色圆圈实际上是对话气泡,旨在打印并粘贴到海报上。

是否有任何出色的 SVG/Canvas 库支持此功能,或者我是否必须从头开始找出我们的方法?


有一个提议的 CSS 功能称为“排除”,它可以使文本在定义的区域内流动:http://www.w3.org/TR/css3-exclusions/ http://www.w3.org/TR/css3-exclusions/

这意味着 SVG 和 Canvas 路径可能被定义为容器,并且文本将在容器内流动/换行。

我确实说过“提议”——这离在浏览器中成为现实还有很长的路要走。

然而...

您可以使用 html canvas 相当轻松地将文本包裹在一个圆圈内

当您沿着圆圈向下移动时,任何行上可显示文本的宽度都会发生变化。

以下是如何确定圆上任何水平线的最大可用宽度

// var r is the radius of the circle
// var h is the distance from the top of the circle to the horizontal line you’ll put text on

var maxWidth=2*Math.sqrt(h*(2*r-h));

您可以通过测量文本的宽度来使文本适合该行 - 一次添加一个单词,直到用完该行的所有可用宽度。

以下是如何使用 canvas 来测量使用当前 context.font 的任何文本:

var width=ctx.measureText(“This is some test text.”).width;

剩下的只是向每行添加文本直至最大行宽,然后开始新行。

如果您更喜欢 SVG,则可以在 SVG 中使用 element.getCompulatedTextLength 方法对文本指标执行类似操作。

这是代码和小提琴:http://jsfiddle.net/m1erickson/upq6L/ http://jsfiddle.net/m1erickson/upq6L/

<!doctype html>
<html lang="en">
<head>

  <style>
      body{ background-color: ivory; padding:20px; }
      canvas{ border:1px solid red;}
  </style>
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>

  <script>

  $(function() {

      var canvas=document.getElementById("canvas");
      var ctx=canvas.getContext("2d");

      var text = "'Twas the night before Christmas, when all through the house,  Not a creature was stirring, not even a mouse.  And so begins the story of the day of Christmas";
      var font="12pt verdana";
      var textHeight=15;
      var lineHeight=textHeight+5;
      var lines=[];

      var cx=150;
      var cy=150;
      var r=100;

      initLines();

      wrapText();

      ctx.beginPath();
      ctx.arc(cx,cy,r,0,Math.PI*2,false);
      ctx.closePath();
      ctx.strokeStyle="skyblue";
      ctx.lineWidth=2;
      ctx.stroke();


      // pre-calculate width of each horizontal chord of the circle
      // This is the max width allowed for text

      function initLines(){

          for(var y=r*.90; y>-r; y-=lineHeight){

              var h=Math.abs(r-y);

              if(y-lineHeight<0){ h+=20; }

              var length=2*Math.sqrt(h*(2*r-h));

              if(length && length>10){
                  lines.push({ y:y, maxLength:length });
              }

          }
      }


      // draw text on each line of the circle

      function wrapText(){

          var i=0;
          var words=text.split(" ");

          while(i<lines.length && words.length>0){

              line=lines[i++];

              var lineData=calcAllowableWords(line.maxLength,words);

              ctx.fillText(lineData.text, cx-lineData.width/2, cy-line.y+textHeight);

              words.splice(0,lineData.count);
          };

      }


      // calculate how many words will fit on a line

      function calcAllowableWords(maxWidth,words){

          var wordCount=0;
          var testLine="";
          var spacer="";
          var fittedWidth=0;
          var fittedText="";

          ctx.font=font;

          for(var i=0;i<words.length; i++){

              testLine+=spacer+words[i];
              spacer=" ";

              var width=ctx.measureText(testLine).width;

              if(width>maxWidth){ 
                  return({
                      count:i, 
                      width:fittedWidth, 
                      text:fittedText
                  }); 
              }

              fittedWidth=width;
              fittedText=testLine;

          }

      }


  });   // end $(function(){});

  </script>
</head>
<body>
    <p>Text wrapped and clipped inside a circle</p>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将文本绕成 svg 或 canvas 中的圆形 的相关文章

  • 自定义 SVG 未加载到我的图像标签中

    目前我正在尝试将自定义 svg 组件加载到图像标签内 但由于某种原因 我无法看到地图组件内的 svg 图像 我的自定义 SVG 文件如下所示 我在 SVG 中加载另一个图像
  • 在 JavaScript 函数中加载图像

    我有获取图像像素颜色的功能 function getImage imgsrc var img img src imgsrc var imageMap new Object img load function var canvas
  • d3.event.translate 在触摸设备的缩放上包含 NaN

    我使用 d3 为我的 svg 编写了一个自定义缩放函数 如下所示 Zoom behavior function myzoom xpos d3 event translate 0 ypos d3 event translate 1 vis a
  • 有没有办法将 SWF 转换为 SVG 格式?

    有没有办法将 FLA 或 SWF 转换为 SVG 格式 它可以是一个软件吗 或者甚至是网络转换器 我尝试了一些方法 但没有一个有效 所有这些似乎都已经过时了 不 SWF 支持的功能太多 而 SVG 格式无法创建有效的 SWF 版本 如果您只
  • R 中 SVG 图形的最佳设备? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想从 R 导出 SVG 图形 似乎有两种选择 RSvgDevice 和 Cairo 有人可以对这些包发表评论吗 是默认的还是明显比另一个
  • 在 d3.js 中操纵鼠标悬停在“点击区域”

    我想show and hideSVG 中的一个节点 当鼠标移到 mouseout 问题是我的节点内部的形状是一条宽度只有1 5px的路径 因此在鼠标悬停事件中不容易击中该区域 这对用户体验肯定不方便 我想知道是否有办法做到这一点打击范围更广
  • SVG img keepAspectRatio Chrome

    当我对 SVG 文件中的图像使用preserveAspectRatio none 时 它 似乎在 Google Chrome 中不起作用 SVG 不会根据图像宽度和高度进行缩放
  • SVG 转 JPG / PNG

    有没有工作模块可以convert a SVG image into像素格式如JPEG or PNG 看看蜡染工具包 具体来说是光栅化器 http xmlgraphics apache org batik tools rasterizer h
  • 将整个网页设计为 SVG 文件

    免责声明 我意识到鉴于标题的荒谬 这听起来像一个巨魔 然而 这是一个真正的问题 我的背景涉及OpenGL x86 汇编 我最近开始学习网络编程 我真的很喜欢 SVG CSS 并且想知道 为什么人们不使用 SVG 设计整个网页 Context
  • SVG线宽问题

    我开始了我的svg学习 我想用svg线做一些技巧吧 但有件事我不明白 我为每个技能创建 2 行 一行是空的 另一行是知识百分比 问题是 前两行的高度是我给出的笔画宽度的一半 其他线都有很好的高度 这是一个 jsbin http jsbin
  • QML改变图像颜色

    我搜索了如何对图像进行着色 格式为 svg 或 png 我尝试用一 个填充图像的矩形覆盖我的图像 但由于我的图像不是矩形 它会给整个矩形着色 而不仅仅是图像 可以用qml改变图像颜色吗 或者 是否可以使用 QPixmap 更改 qt 使用
  • 如何按比例缩放 SVG

    我已从 Illustrator 导出 SVG 并希望设置 SVG 的高度并按比例设置宽度比例 这是 SVG 示例
  • 简单的 svg css 进度圈

    我正在尝试寻找一种方法来实现没有动画的简单进度圈 静态 我发现的示例具有非常不同的百分比偏移量 如下例所示 如何以这样的方式制作进度圈 如果我提供偏移量为 50 那么它恰好是 50 半填充 u absoluteCenter position
  • innerHTML 未写入 svg 组 Firefox 和 IE

    我正在做一个项目 遇到了障碍 在 Chrome 中 它按预期工作 但在 Firefox 和 IE 中则不然 下面的代码实际上只是真实项目代码的非常简化的版本 基本上我正在尝试替换 svg 的每组中的圆圈 因此 我从预编码的圆圈开始 然后删除
  • SVG 内部跨度与文本不在同一行

    我在一个跨度内有一个 SVG 文件 同时包含文本 文本和 SVG 的高度相同 但是 SVG 与文本不在同一行 相关jsfiddle https jsfiddle net tcrnjd53 https jsfiddle net tcrnjd5
  • 使 D3 响应式:viewBox 与 resize()?

    我必须构建在平板电脑 桌面显示器以及某些情况下非常大的 4k 高分辨率影院尺寸显示器上都能正常运行的 d3 可视化效果 因此 我试图找出使用 SVG 的 viewBox 属性和 preserveaspectratio 与调用调整大小函数以在
  • Jest/Enzyme SVG Sprites 意外令牌 <

    我在使用 SVG 精灵在组件上使用 Jest 和 Enzyme 创建快照测试时遇到问题 我正在使用 svg sprite loader 包 https github com kisenka svg sprite loader https g
  • 尽管 getBoundingClientRect() 是假的,但如何将事件坐标转换为 SVG 坐标?

    我正在尝试根据鼠标的位置在 SVG 元素上动态绘制内容 不幸的是 我很难将 mousemove 事件中的鼠标坐标转换为 SVG 元素的坐标空间 这是我一直在测试的一个有缺陷的函数 CylinderDemo prototype handleM
  • SVG 剪辑路径在 Safari 上不起作用

    我有一个简单的动画 从下往上填充 svg 然后淡出 填充是使用clipPath随着使用path with a stroke dasharray stroke dashoffset 问题是clipPath在 Safari 上似乎完全被忽略了
  • 快速响应的交互式图表/图形:SVG、Canvas 还是其他?

    我正在尝试选择正确的技术来更新一个项目 该项目基本上在可缩放 可平移的图表中渲染数千个点 当前使用 Protovis 的实现性能不佳 在这里查看 http www planethunters org classify http www pl

随机推荐

  • 自定义开关按钮动画

    我用的是定制的开关按钮 in the 自定义开关按钮 https stackoverflow com questions 30593193 creating sliding on off switch button in javafx an
  • Flexbox 项目之间的间距

    这就是我要的 但这是我最接近的 body margin 0 padding 0 border 1px solid red flex display ms flexbox display webkit box display webkit f
  • 如何在 flink 独立安装上进行 kerberos 身份验证?

    我有一个独立的 Flink 安装 我想在其上运行一个将数据写入 HDFS 安装的流作业 HDFS 安装是 Cloudera 部署的一部分 需要 Kerberos 身份验证才能读取和写入 HDFS 由于我没有找到有关如何使 Flink 与受
  • GLES20Canvas.nDrawDisplayList 很慢

    我有一个正在尝试显示的自定义视图 但是我看到它上面有一堆抖动 一切都滚动缓慢 并且响应速度不及应有的水平 我使用了traceview并看到了 GLES20Canvas nDrawDisplayList 似乎要花很多时间来执行 有什么帮助吗
  • Javascript 中如何检测对象是否已被垃圾回收?

    我正在构建一个 JavaScript 游戏 它创建一个Level使用 var 的对象 function start var myGameLevel new Level 2 This Levelobject 有很多功能 主要是向 DOM 添加
  • C++ 函数模板,未定义的架构符号[重复]

    这个问题在这里已经有答案了 有人可以向我解释为什么以下内容无法编译吗 希望我错过了明显的事情 函数 hpp template
  • 防止 Sympy 重新排列方程

    也许我忽略了显而易见的事情 但是如何防止 sympy 重新排列方程呢 我在 iPython 笔记本中使用 Sympy 因此我可以轻松地将 Latex 代码复制粘贴到 Lyx 但我希望方程的顺序与我定义的顺序相同 例如 灰体辐射与其温度的关系
  • 列出 SQL Server 2012 架构中所有表的名称

    我在 SQL Server 2012 中有一个架构 是否有一个命令可以在 SQL 中运行来获取该架构中由用户填充的所有表的名称 我知道 MySQL 有一个类似的查询SHOW TABLES 但这不适用于 SQL Server 你真的应该使用I
  • 访客模式:遍历客户端或访客中的树元素

    早上好 stackoverflow 我目前正在 AST 之类的东西上实现访问者模式 现在我的问题是 如何迭代元素 我认为将对象返回给访问者并让访问者从那里开始遍历更符合逻辑 因为当您想以不同的方式遍历对象时 您可以保持灵活性 另一方面 人们
  • FIRAnalyticsConnector:为 Mac Catalyst 构建,但在为 iOS Simulator 构建的目标文件中链接

    当尝试使用 Catalyst 为 Mac 构建时 我收到以下构建错误 FIRAnalyticsConnector FIRConnectorUtils 77ff1e12be6740765c87f1be0d421683 o building f
  • Terraform databricks 无法配置默认凭据

    我们正在通过 Azure 管道运行 terraform 以创建 databricks 工作区和相关资源 但是当 Terraform 的应用阶段到达获取最新版本的 Spark 的阶段时 该过程会引发错误 错误是 Error default a
  • 自动目录树更新

    我不确定这是否可能 但我希望在编译过程中将多个 rst 文件放入一个目录中 我希望这些文件自动插入到toctree 我该怎么办 您可以使用glob启用通配符的选项 像这样 toctree glob 这会将同一目录中的所有其他 rst 文件添
  • 如何区分提交与其父提交

    除了编写别名或脚本之外 是否有更短的命令来获取特定提交的差异 git diff 15dc8 15dc8 如果您只提供单个提交 IDgit diff 15dc8 它与针对 HEAD 的提交不同 Use git show COMMIT 它将向您
  • 可以突出显示街道的一部分吗?

    我需要突出显示两个十字路口之间的街道部分 我发现一年多前就有人提出过类似的问题 请参阅here https stackoverflow com questions 2155032 highlighting whole street with
  • Kotlin 中的 Swift 'if let' 语句等效项

    在 Kotlin 中是否有与下面的 Swift 代码等效的代码 if let a b val else 您可以使用let 函数如下 val a b let If b is not null run If b is null 请注意 您需要调
  • 将双变量视为布尔值

    测试 double 变量是否等于 0 的更好方法 效率 最佳实践 是什么 1 if a double else OR 2 if a double 0 else 第二个通常更好 更明确地说明您正在做什么 我通常更喜欢if a double 0
  • Zend Framework:如何将旧路由 301 重定向到新的自定义路由?

    我有大量旧路线 需要将其重定向到新路线 我已经在 Bootstrap 中定义了我的自定义路由 protected function initRoutes router Zend Controller Front getInstance gt
  • 如何将模板添加到 Kendo 网格工具栏

    我正在尝试将自定义模板添加到 Kendo MVC 网格 我的模板应该包含两件事 创建按钮以将新记录添加到网格中 自动完成框用于过滤网格中的数据 我正在尝试以下代码 ToolBar toolbar gt toolbar Template
  • 启用/禁用每个控制器/操作方法的会话状态

    我们正在构建一个 ASP NET MVC 应用程序 该应用程序将部署在支持缓存等功能的硬件负载平衡器后面 我们的建议是手动定义负载均衡器应缓存哪些 URL 模式 这对我们来说将是一个相当简单的过程 因为我们有相对静态的 目录 页面 然后是非
  • 将文本绕成 svg 或 canvas 中的圆形

    将文本适合网站上的圆圈 使其随圆圈的曲线流动而不是矩形边界框的一个好的解决方案是什么 这就是我想要实现的目标 页面上有许多黑色圆圈 固定大小 每个圆圈旁边都有一个文本区域 当文本输入到文本区域时 它会出现在黑色圆圈中 以两个轴为中心 如果输