【问题标题】:How to make SVG image pattern fill move with object?如何使 SVG 图像图案填充随对象移动?
【发布时间】:2019-11-29 00:19:53
【问题描述】:

我有一些使用 fill="url(#background) 平铺图像背景的 SVG 对象,其中我将 #background 定义为仅包含 imagepattern

但是,当对象通过设置其x/y 属性(或cx/cy,或任何其他定义偏移量)重新定位时,背景不会随之移动。

如何让背景也移动?从How would I move an SVG pattern with an element 我尝试设置patternContentUnits='objectBoundingBox' 但这只是将图像变成纯色斑点(奇怪的是,根据图像着色,好像它只是第一个像素或类似的东西)。

这是一个 jsfiddle 说明所有这些 - 顶部 rect 已变成纯色,然后底部 rect 具有背景图像,但它不会与 rect 一起移动:

http://jsfiddle.net/x8nkz/17/

我知道,如果您使用 transform="translate(...)" 而不是设置 x/y 属性,背景确实也会被翻译,但我正在使用的现有代码库不使用 translate 进行定位(它会对应用程序的其余部分产生其他意想不到的后果)。

提前感谢您的帮助。

【问题讨论】:

    标签: javascript svg


    【解决方案1】:

    我实际上遇到了同样的问题并找到了解决方案。我已经分叉了你的小提琴来展示这些变化。基本上,您删除 patternContentUnits 属性,因为它在这里没有帮助,并在每次更新后更新图像的 x 属性以匹配 rect 对象的属性。

    http://jsfiddle.net/RteBM/2/

    更新的 HTML:

    <svg xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
    <title>basic pattern</title>
    <defs>
        <pattern id="pat1" width="179" height="132" patternUnits="userSpaceOnUse">
             <image x="0" y="0" width="179" height="132" xlink:href="http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/honey_im_subtle.png"></image>
        </pattern>
        <pattern id="pat2" width="179" height="132" patternUnits="userSpaceOnUse">
            <image x="0" y="0" width="179" height="132" xlink:href="http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/honey_im_subtle.png"></image>
        </pattern>
    </defs>
    <rect id="rect1" x="0" y="0" width="179" height="132" fill="url(#pat1)"/>
    <rect id="rect2" x="0" y="150" width="179" height="132" fill="url(#pat2)"/>
    </svg>
    

    更新的 JS:

    var i = 0;
    var newX;
    setInterval(
        function(){
            $('rect').attr('x', Math.sin(i+=.01)*100+100);      
            $('#pat1').attr('x', $("#rect1").attr('x'));
        }, 100);
    

    【讨论】:

      【解决方案2】:

      如果您使用 objectBoundingBox 单位,则宽度为 1(或 100%)是对象的宽度,因此 178 将是该宽度的 178 倍。你可能想要

      <pattern id="pat1" width="179" height="132" patternUnits="userSpaceOnUse" patternContentUnits="objectBoundingBox">
          <image width="1" height="1" xlink:href="http://subtlepatterns.subtlepatterns.netdna-cdn.com/patterns/honey_im_subtle.png"></image>
      </pattern>
      

      但这不会使模式移动。你将需要某种转换来做到这一点。如果你不能把它放在&lt;rect&gt; 上,也许你可以让矩形成为&lt;g&gt; 元素的子元素,然后转换&lt;g&gt; 元素。

      【讨论】:

      • 我刚刚在 jsfiddle 上试了一下。它不起作用 - 背景仍然没有随着矩形移动。
      【解决方案3】:

      尝试将 patternUnits 的值设置为“objectBoundingBox”。

      【讨论】:

      • 我刚刚在 jsfiddle 上试了一下。它不起作用 - 我看不出有什么区别。
      【解决方案4】:

      使用“嵌套 SVG 文档”对可拖动元素进行分组

      图案位置相对于第一个父 SVG 文档

      fiddle here

      <html>
      
      <!-- svg.js + svg.draggable.js -->
      <script type="text/javascript"
      src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@latest/dist/svg.min.js"></script>
      <script type="text/javascript"
      src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.draggable.js@latest/dist/svg.draggable.min.js"></script>
      
      <div id="canvas"></div>
      
      <script type="text/javascript">
      
      // create canvas
      var draw = SVG().size(200, 200).addTo('#canvas')
      
      // pattern of checkerboard
      var patt = draw.pattern(20, 20)
      patt.rect(20, 20).fill({color: '#fff'})
      patt.rect(10, 10)
      patt.rect(10, 10).move(10, 10)
      
      // nested svg document
      var nested = draw.nested()
      
      // rect + pattern
      nested.rect(80, 80).attr({
          fill: patt
      })
      
      // drag on
      nested.draggable()
      
      
      
      /*
      // this works too, but its slow:
      
      // group + draggable
      var group = draw.group().draggable()
      
      // move handler
      group.on('dragmove', (e) => {
        const {x, y} = e.detail.box
        patt.move(x, y)
      })
      
      // rect with pattern
      var r = group.rect(80, 80).attr({
          fill: patt
      })
      */
      
      </script>
      </html>
      

      【讨论】:

        猜你喜欢
        • 2015-06-03
        • 2013-09-06
        • 2013-12-19
        • 2013-07-21
        • 1970-01-01
        • 2013-07-27
        • 2012-06-14
        • 2014-03-21
        • 2011-09-30
        相关资源
        最近更新 更多