首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SVG动态定位与尺寸

SVG动态定位与尺寸
EN

Stack Overflow用户
提问于 2022-11-22 19:57:25
回答 1查看 41关注 0票数 0

我有一个web应用程序,从笛卡儿点(行、路径等)呈现来自数据库的svg元素。

我有一个要求,最终用户可以上传一个svg文件(图标),并拖动图标,以适应在应用程序中已经定义和呈现的点的特定界限。

例如(请参阅片段),用户可以上传“x”图标,并将其拖到由两点定义的绿线附近,这将导致图标被抓拍并调整到线的大小--左上角被抓拍到直线起始点,图标的宽度延伸到线的终点。同样的情况是,文件图标被抓取到红线。这是在使用js拖动过程中动态完成的。为了保持简单,我省略了片段中的js,因为我确信答案在于svg属性和或我可以用js设置的样式,但是svg属性/值是我无法确定的。

我试过的一切,我想。考虑到我正在嵌套svg元素,我将BBox值作为偏移使用图标svg元素上的x和y属性,并将其移动,而不是移到起点。我也尝试过翻译,但没有成功。我可以移动和调整尺寸,但不能移动到我需要的坐标。如果可能的话,我不想更改图标svg,所以我宁愿保留它的viewBox原样。

代码语言:javascript
复制
<svg height="700" width="700" fill="#e6e6e6" xmlns="http://www.w3.org/2000/svg">

<svg viewBox="0 0 512 512">
  <path d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4  L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1  c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1  c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z"/>
</svg>

<svg viewBox="0 0 380 511.7">
  <path fill-rule="nonzero" d="M26.18 0h221.14c3.1 0 5.85 1.51 7.56 3.84l122.88 145.08a9.27 9.27 0 0 1 2.21 6.05l.03 330.55c0 7.13-2.98 13.68-7.72 18.42l-.03.04c-4.75 4.74-11.29 7.72-18.43 7.72H26.18c-7.13 0-13.69-2.96-18.45-7.71l-.03-.04C2.97 499.22 0 492.69 0 485.52V26.18C0 19 2.95 12.46 7.68 7.72l.04-.04C12.46 2.95 19 0 26.18 0zm335.06 164.7c-134.78-5.58-134.35-17.38-129.82-134.02l.45-11.92H26.18c-2.05 0-3.91.83-5.26 2.16a7.482 7.482 0 0 0-2.16 5.26v459.34c0 2.02.84 3.88 2.18 5.23 1.36 1.35 3.22 2.19 5.24 2.19h327.64c2.01 0 3.86-.85 5.22-2.2 1.35-1.36 2.2-3.21 2.2-5.22V164.7zM250.25 27.32l-.15 4.01c-3.73 96.04-4.22 109.01 100.23 114.16L250.25 27.32z"/>
</svg>

<line x1="100" y1="20" x2="200" y2="20" stroke="green" />
<line x1="300" y1="20" x2="350" y2="20" stroke="red" />
</svg>

强文本

EN

回答 1

Stack Overflow用户

发布于 2022-11-27 16:15:05

虽然可能有几种方法来实现这一点,但我想出了一种方法,我将继续前进。与此混淆的主要原因是我对svg viewBox和坐标系统如何工作缺乏了解。

关键是为每个嵌套的svg根据其viewBox坐标定义一个新的BBox值。这样做的目的是在没有“空格”的情况下对绘图进行帧化,以便能够将其放置在所需的坐标上。一旦您拥有了BBox数据,您就可以设置viewBox并做一些简单的计算来正确地设置所需的高度和宽度(这两个都必须为嵌套的svg定义)。在更新viewBox、宽度和高度之后,可以将svg移动到新位置。

代码语言:javascript
复制
$( document ).ready(function() {
        const svg = document.querySelectorAll('svg.a');
        svg.forEach(x => {
          setSvg(x);
        });
    });

    function setSvg(svg){
      const { xMin, xMax, yMin, yMax } = [...svg.children].reduce((acc, el) => {
            const { x, y, width, height } = el.getBBox();
            if (!acc.xMin || x < acc.xMin) acc.xMin = x;
            if (!acc.xMax || x + width > acc.xMax) acc.xMax = x + width;
            if (!acc.yMin || y < acc.yMin) acc.yMin = y;
            if (!acc.yMax || y + height > acc.yMax) acc.yMax = y + height;
            return acc;
        }, {});
        const viewbox = `${xMin} ${yMin} ${xMax - xMin} ${yMax - yMin}`;

        let newWidth = $(svg).attr('data-new-width');
        let newPosition = $(svg).attr('data-new-position');
        let newHeight = newWidth*(yMax - yMin)/(xMax - xMin);

        svg.setAttribute('width', newWidth);
        svg.setAttribute('height', newHeight);
        svg.setAttribute('x', newPosition.split(",")[0]);
        svg.setAttribute('y', newPosition.split(",")[1]);
        svg.setAttribute('viewBox', viewbox);
    }
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="700" width="700" fill="#e6e6e6" xmlns="http://www.w3.org/2000/svg">

    <svg class="a" data-new-width="100" data-new-position="100,20" viewBox="0 0 512 512">
      <path d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4  L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1  c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1  c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z"/>
    </svg>

    <svg class="a" data-new-width="50" data-new-position="300,20" viewBox="0 0 380 511.7">
      <path fill-rule="nonzero" d="M26.18 0h221.14c3.1 0 5.85 1.51 7.56 3.84l122.88 145.08a9.27 9.27 0 0 1 2.21 6.05l.03 330.55c0 7.13-2.98 13.68-7.72 18.42l-.03.04c-4.75 4.74-11.29 7.72-18.43 7.72H26.18c-7.13 0-13.69-2.96-18.45-7.71l-.03-.04C2.97 499.22 0 492.69 0 485.52V26.18C0 19 2.95 12.46 7.68 7.72l.04-.04C12.46 2.95 19 0 26.18 0zm335.06 164.7c-134.78-5.58-134.35-17.38-129.82-134.02l.45-11.92H26.18c-2.05 0-3.91.83-5.26 2.16a7.482 7.482 0 0 0-2.16 5.26v459.34c0 2.02.84 3.88 2.18 5.23 1.36 1.35 3.22 2.19 5.24 2.19h327.64c2.01 0 3.86-.85 5.22-2.2 1.35-1.36 2.2-3.21 2.2-5.22V164.7zM250.25 27.32l-.15 4.01c-3.73 96.04-4.22 109.01 100.23 114.16L250.25 27.32z"/>
    </svg>

    <line x1="100" y1="20" x2="200" y2="20" stroke="green" />
    <line x1="300" y1="20" x2="350" y2="20" stroke="red" />
  </svg>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74538285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档