如何避免 svgs 的foreignObjects 内的元素缩放?

2024-03-16

我想使用 svg 作为 div 元素的容器,该元素应包含多个元素。目前它看起来像这样:

<body>
    <svg width="100%" height="100%" viewBox="0 0 45 90" version="1.1" xmlns="http://www.w3.org/2000/svg" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
       <path d="M45.02,17.449l0,-5.837l-0.324,0c0,-3.841 0,-6.21 0,-6.344c0,-0.786 0.105,-3.078 -2.657,-3.659c-5.996,-1.263 -19.539,-1.352 -19.539,-1.352c0,0 -13.543,0.089 -19.539,1.352c-2.762,0.58 -2.657,2.873 -2.657,3.659c0,0.192 0,4.987 0,12.133l-0.324,0l0,14.537l0.324,0c0,22.9 0,52.313 0,52.794c0,0.786 -0.105,3.079 2.656,3.66c5.997,1.262 19.54,1.351 19.54,1.351c0,0 13.542,-0.089 19.539,-1.351c2.762,-0.581 2.657,-2.874 2.657,-3.66c0,-0.594 0,-45.159 0,-67.283l0.324,0Zm-22.52,-13.778c0.535,0 0.969,0.434 0.969,0.969c0,0.536 -0.434,0.97 -0.969,0.97c-0.535,0 -0.969,-0.435 -0.969,-0.97c0,-0.536 0.434,-0.969 0.969,-0.969Zm20.262,75.595l-40.525,0l0,-71.234l40.524,0l0,71.234l0.001,0Z" style="fill-rule:nonzero;"></path>
       <foreignObject x="2.238" y="8.019" width="40" height="71">
          <div id="screen">
             I'm a very long text. Why am I so big?
          </div>
       </foreignObject>
    </svg>
</body>

CSS

html, body{
  width: 100%;
  height: 100%;
}

#screen{
  background: green;
  overflow: scroll;
  width: 100%;
  height: 100%;
  font-size: 10px;
}

JSFiddle https://jsfiddle.net/7ttps7a7/1/

我的问题是 screen-div 内的所有元素都比预期大得多。例如查看滚动条或文本的大小。

我假设内容foreignObject缩放比例与 svg 相同。有办法避免这种情况吗?我可以规范化里面的div吗foreignObject不缩放?


svg 是名词项目中 Martin Jordan 的“智能手机” https://thenounproject.com/MartinJordan/uploads/?i=32550


我能想到的唯一解决方案是使用 JavaScript 动态调整大小和反缩放foreignObject基于 viewBox 尺寸与offsetWidth and offsetHeight的外层的<svg>.

例如,在这个演示中,我碰巧将 SVG 的大小硬编码为 viewBox 尺寸的四倍。为了解决这个问题,我做了foreignObject四倍大,但随后缩小到四分之一:

<foreignObject width="164" height="288" transform="translate(2,8) scale(0.25,0.25)">

https://jsfiddle.net/7ttps7a7/3/ https://jsfiddle.net/7ttps7a7/3/

一个好的通用解决方案是在任何对象的自定义命名空间中放置一个额外的属性foreignObject,然后加载一个 JavaScript 库来查找此类元素并动态调整它们(并随着 SVG 大小的变化而调整它们)。

请注意,比较offsetWidth(和身高)vsviewBox宽度(和高度)需要考虑的值preserveAspectRatio https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio准确地说,是 SVG 上的属性。

Edit:我创建了一个小型库来执行此操作

  • Library: http://phrogz.net/SVG/fixed-size-foreignObject.js http://phrogz.net/SVG/fixed-size-foreignObject.js
  • Demo: http://phrogz.net/SVG/fixed-size-foreignObject.html http://phrogz.net/SVG/fixed-size-foreignObject.html

使用方法:

  1. 将库包含在 HTML 或 SVG 页面中。
    请下载并托管在您自己的网站上;我不是 CDN。
  2. 请务必使用x and y属性来放置你的<foreignObject>, and width and height值来调整它的大小。
  3. 使用以下其中一项:

    fixedSizeForeignObject( someForeignObjectElement );
    fixedSizeForeignObjects( arrayOfForeignObjectElements );
    

怎么运行的:

  1. 当一个foreignObject被添加到元素列表中以保持调整大小时,它的原始x、y、宽度、高度值将被记录。拥有foreignObject 的SVG 元素将添加到要观看的SVG 元素列表中。
  2. 当窗口调整大小时,会触发代码:(a) 计算每个 SVG 的比例(实际像素与 viewBox 大小),然后 (b) 对于注册的每个foreignObject,它会调整宽度/高度以使其正确,然后缩小元素以适应原来的位置。

如果我的网站关闭(不太可能),我将复制/粘贴该库:

(function(win){
  const svgs, els=[];

  win.fixedSizeForeignObjects = function fixedSizeForeignObjects(els) {
    els.forEach( fixedSizeForeignObject );
  }

  win.fixedSizeForeignObject = function fixedSizeForeignObject(el) {
    if (!svgs) { svgs = []; win.addEventListener('resize',resizeSVGs,false) }
    let svg=el.ownerSVGElement, found=false;
    for (let i=svgs.length;i--;) if (svgs[i]===svg) found=true;
    if (!found) svgs.push(svg);
    let info = {
      el:el, svg:svg,
      w:el.getAttribute('width')*1, h:el.getAttribute('height')*1,
      x:el.getAttribute('x')*1, y:el.getAttribute('y')*1
    };
    els.push(info);
    el.removeAttribute('x');
    el.removeAttribute('y');
    calculateSVGScale(svg);
    fixScale(info);
  }

  function resizeSVGs(evt) {
    svgs.forEach(calculateSVGScale);
    els.forEach(fixScale);
  }

  function calculateSVGScale(svg) {
    let w1=svg.viewBox.animVal.width, h1=svg.viewBox.animVal.height;
    if (!w1 && !h1) svg.scaleRatios = [1,1]; // No viewBox
    else {
      let info = win.getComputedStyle(svg);
      let w2=parseFloat(info.width), h2=parseFloat(info.height);
      let par=svg.preserveAspectRatio.animVal;
      if (par.align===SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE) {
        svg.scaleRatios = [w2/w1, h2/h1];
      } else {
        let meet = par.meetOrSlice === SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET;
        let ratio = (w1/h1 > w2/h2) != meet ? h2/h1 : w2/w1;
        svg.scaleRatios = [ratio, ratio];
      }
    }
  }

  function fixScale(info) {
    let s = info.svg.scaleRatios;
    info.el.setAttribute('width', info.w*s[0]);
    info.el.setAttribute('height',info.h*s[1]);
    info.el.setAttribute('transform','translate('+info.x+','+info.y+') scale('+1/s[0]+','+1/s[1]+')');
  }
})(window);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何避免 svgs 的foreignObjects 内的元素缩放? 的相关文章

  • jQuery 函数 .bind 在 IE 中不起作用

    这是我的网站 http johns webdesign com port html 如果您单击小缩略图 则会显示更大的图像 在 Chrome 中它工作得很好 但是当我在 IE9 中尝试它时它什么也没做 这是我的代码 jQuery JavaS
  • 使用 angularjs 在 Internet Explorer 中获取 Blob url

    鉴于此代码 来自其他人 var module angular module myApp module controller MyCtrl function scope scope json JSON stringify a 1 b 2 mo
  • 自定义元素可以扩展输入元素吗?

    使用Web组件规范 是否可以扩展特定类型的
  • 在跨开口的 Bootstrap 弹出窗口中保留复选框

    我在引导弹出窗口内有复选框 我将其用作表单的一部分 当用户打开弹出窗口 选择一些复选框 关闭弹出窗口 然后重新打开弹出窗口时 我遇到问题 新打开的弹出窗口不会显示用户上次打开弹出窗口时选中的框 我需要用户的选择在弹出窗口启动时保持不变 我猜
  • CSS - 100% 高度,带页眉和页脚

    我正在尝试设计一个带有页眉 延伸至 100 垂直景观 减去页眉和页脚 的主 div 和页脚的页面 就像这张照片 我可以让标题和主 div 正常工作 像这样 div div class header div HEADER div div cl
  • JavaScript CSV 验证

    如何检查文本框中的逗号分隔值并在未找到时发出警报 如果有的话 里面应该有字符 比如A B C D function validate validate text box
  • jquery无法获取data属性值

    我正在尝试在 jQuery 中设置一个变量 该值应该在按钮的单击事件上设置 onclick 事件触发 但 x10Device 变量仍然存在undefined 我使用的是jquery 1 7 1 jQuery x10Device this d
  • 能够使用 Bootstrap 3 网格系统指定选择元素的宽度

    我有以下内容
  • JSF 不呈现自定义 HTML 标记属性

    我想向我的登录表单添加一些 iOS 特定的标签属性 如果我查看我的网页源代码 就会发现自动更正 自动大写和拼写检查属性不存在 这是什么原因呢 我正在使用 JSF 2 x
  • http和https在编程中有什么区别[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我只知道 s 代表 安全 用户永远不
  • 使用 IE9、10、11 的 CSS 将比例打印到 50% 等百分比

    Zoom css 属性不适用于 IE9 10 11 观察到打印预览 UI 令人不安 默认比例为 缩小以适合 当我将此比例从 缩小 更改为适合 50 时 页面显示正常 打印预览 任何人都可以帮助我如何使用 CSS 代码将比例设置为 50 为页
  • 在 UIWebView 中禁用复制和粘贴

    几乎 我已经尝试了一切方法来禁用复制 粘贴UIWebView但对我来说没有任何作用 我正在加载我的UIWebView来自字符串 字符串数组 如下所示 webView loadHTMLString NSString stringWithFor
  • 如何防止输入文本中出现“后重音”

    我相信这是一个简单的问题 但在谷歌上搜索几个小时后我找不到任何答案 也许我无法在搜索中使用正确的单词 P 我有一个 javascript 方法 可以防止用户用数字以外的其他字符填充文本框 如下面的代码所示 它在 KeyDown 事件中使用
  • IE localStorage 事件失火

    在 Internet Explorer 9 和 10 中 localStorage 实现意外地触发事件 这里有很棒的线索 Chrome 的 localStorage 实现存在错误 https stackoverflow com questi
  • 为什么我不能同时使用背景图像和颜色?

    我想做的是展示两者background color and background image 这样我的一半div将覆盖右侧的阴影背景图像 而左侧的另一部分将覆盖背景颜色 但是当我使用background image 颜色消失 完全可以使用颜
  • 如何使用 Javascript 在 html 文件中搜索字符串?

    我有 5 个 html 文件 并且有一个搜索表单 我想用它来搜索这些 html 文件中的文本
  • 为什么我的 D3 SVG 图上的轴不会更新?

    I have 简单的 D3 散点图 http www raxacoricofallapatorius com test scattertest html我在显示数据的几个不同属性之间切换 但是虽然我可以更改数据点 并按照我想要的方式进行转换
  • 悬停时的 CSS 过渡

    我有个问题 实际上 当我将鼠标悬停在对象上时 我尝试在 div 上进行转换 所以基本上我有一个div 当我将鼠标悬停在div上时 它应该在其顶部显示另一个div 但是它应该被转换 这样悬停效果会更平滑 如果我有这两个 div 怎么可能 di
  • 如果 jquery 验证激活,如何在单选按钮中放置红色边框[重复]

    这个问题在这里已经有答案了 我的问题是 如果 jquery 验证像示例图片中那样激活 我无法使单选按钮具有红色边框 任何人都可以帮我解决这个问题吗 http i38 photobucket com albums e149 eloginko
  • 如何给URL添加变量?

    我正在尝试从网站收集数据 我有一个 Excel 文件 其中包含该网站的所有不同扩展名 F i www example com example2 我有一个脚本可以成功从网站中提取 HTML 但现在我想为所有扩展自动执行此操作 然而 当我说 s

随机推荐

  • Silverlight 与 IIS 10.0 上的 RIA 服务导致 404 错误

    尝试使用 WCF RIA 服务迁移现有的正在运行的 Silverlight 应用程序IIS 6 0 to IIS 10 0 on W视窗服务器 2016但应用程序失败返回404错误s 当我在服务器上安装 Visual Studio 并尝试运
  • 自动运行多个 vim 命令和击键

    我想在 vim 中自动运行多个命令 即通过键入 repl 命令是 ConqueTerm lein repl
  • AChartEngine 的 Android 问题:在边距中设置图像

    是否可以将图像设置为背景边距 我通常使用mRenderer setMarginsColor Color argb 0x00 0x01 0x01 0x01 但我想设置一个图像 您无法在 AChartEngine 中将图像设置为背景 因为它是开
  • 使用点“.” MVC4 路由中的角色

    我目前正在提供来自数据库表的图像 这些图像都是相同的文件类型 我想要字符点 路线 但尚未取得任何成功 据我了解 ISAPI 处理程序可能会导致与此相关的问题 我只是不确定如何添加和排除以允许 ASP NET 处理此路由 routes Map
  • jQuery ajax json 响应的长度未定义且数据不正确

    我试图获取一个在服务器端转换为 json 对象的字典对象 以及正确的内容类型标头 但由于某种原因 即使我可以访问部分数据 其他部分也不会显示up 和 jquery 中的 json 对象的长度等于 0 这是我的 jquery 调用 ajax
  • 什么是 __main__.py?

    是什么 main py文件 我应该在其中放入什么样的代码 什么时候应该有一个 通常 Python 程序是通过在命令行上命名 py 文件来运行的 python my program py 您还可以创建一个充满代码的目录或 zip 文件 并包含
  • Antlr 语法生成无效的 C# 代码

    我正在尝试使用 ANTLR 和 StringTemplate 库开发一个 C 代码生成器 AntlrWorks 可以生成 C 解析器和词法分析器文件 而不会报告任何错误 但是 c 解析器代码无效 无法在 Visual Studio 中编译
  • Celery 3.0.1 中的框架错误

    我最近从 2 3 0 升级到 Celery 3 0 1 所有任务都运行良好 很遗憾 我经常收到 帧错误 异常 我还运行主管来重新启动线程 但由于这些线程从未真正被杀死 主管无法知道 celery 需要重新启动 有没有人见过这个 2012 0
  • 在 AWS Code Pipeline 中使用 docker compose 时出错

    我正在使用 AWS Code Pipeline 部署我的 dockerized Django 应用程序 但遇到了一些 Docker 错误 error Service proxy failed to build toomanyrequests
  • 如果满足特定条件,则停止沿特定深度的 boost::depth_first_search

    我在用着BGL http boost org doc libs 1 45 0 libs graph doc table of contents html来存储我的 DAG 顶点有状态 考虑到其中一个顶点的状态发生变化 我想更新依赖顶点 我可
  • 用于格式化一系列单元格并根据 Google 电子表格中的日期插入特定文本的脚本

    我有一个规划器类型的 Google 电子表格 其中每天有 8 10 个用户添加数据 当我向单元格添加日期时 我希望对该日期之后同一行中的所有单元格进行格式化并添加类似 ENDED 的文本值 目前 我正在使用条件格式和 ArrayFormul
  • -[NSRangeException raise] 上的符号异常断点

    在 Xcode 中添加符号断点为您提供了一个示例模板 NSException raise 我想做同样的事情但是具体来说 on NSRangeException raise 原因是我想断点only关于特定数组边界异常 例如 Terminati
  • 如何使用 Traefik 进行 WebSocket 后端

    我正在尝试为 WebSocket 应用程序配置 Traefik 我只是尝试在 docker 上使用一个简单的 WS 应用程序 https hub docker com r jmalloc echo server https hub dock
  • 过滤空手道测试响应对象以获得子列表?

    鉴于此功能文件 Feature test Scenario filter response def response a a b a c a d ab e ab f ab g ac h ac i ac
  • 建模:Xml 与关系数据库

    我想知道是否有最佳实践来决定何时应使用 XML 对系统进行建模以及何时应使用关系数据库进行建模 我知道您可以将 XML 存储在数据库中 但是对系统进行建模之间存在巨大差异使用标准化数据库表并使用 XML 模式对系统进行建模 为了具体起见 假
  • 从 rpy2 传递到 R 的什么对象?

    我无法使以下代码工作 尽管我没有看到此错误在 R 中严格工作 from rpy2 robjects packages import importr from rpy2 import robjects import numpy as np f
  • R 中的 Markdown 表到数据框

    有多种方法可以将数据框转换为 Markdown 表 但是 给定 Markdown 表 如何转换回数据帧 给定一个表格 Table Header Second Header Table Cell Cell 2 Cell 3 Cell 4 或者
  • Python函数参数:元组/列表

    我的函数需要一个列表或元组作为参数 它并不真正关心它是什么 它所做的只是将其传递给另一个接受列表或元组的函数 def func arg arg is tuple or list another func x do other stuff h
  • 工厂女孩在我的开发数据库中保存记录

    我有一个非常奇怪的问题 我不知道应该去哪里找到它 我正在使用 rspec 和 Factory Girl 开发一个 Rails 3 应用程序进行测试 由于某种原因 每当我运行任何rails命令 例如 rake数据库 启动开发服务器等 时 都会
  • 如何避免 svgs 的foreignObjects 内的元素缩放?

    我想使用 svg 作为 div 元素的容器 该元素应包含多个元素 目前它看起来像这样