使用重复的嵌套SVG元素

时间:2017-01-24 08:53:50

标签: svg snap.svg

我在使用snap.svg时遇到了以下问题。

我想在主要内部使用嵌套的SVG元素。假设这个嵌套的一个具有这样的结构:

<svg width="71" height="101" viewBox="0 0 71 101">
<defs>
    <rect id="a" width="70" height="100" rx="5"/>
    <mask id="d" width="70" height="100" x="0" y="0" fill="#fff">
    <use xlink:href="#a"/>
    </mask>
    <rect id="b" width="70" height="100" rx="5"/>
    <mask id="e" width="70" height="100" x="0" y="0" fill="#fff">
    <use xlink:href="#b"/>
    </mask>
    <pattern id="f" width="6" height="5" x="-6" y="-5" patternUnits="userSpaceOnUse">
    <use transform="scale(.5)" xlink:href="#tipstercard-c"/>
    </pattern>
    <image id="c" width="12" height="10" xlink:href="data:image/png;base64,..."/>
</defs>
<g fill="none" fill-rule="evenodd" transform="translate(.338 .194)">
    <use fill="#212120" stroke="#FFF" stroke-width="4" mask="url(#tipstercard-d)" xlink:href="#a"/>
    <use fill="url(#f)" fill-opacity=".1" stroke="#FFF" stroke-width="4" mask="url(#e)" style="mix-blend-mode:luminosity" xlink:href="#b"/>
    <path fill="#FFF" d="M20.22 47.784v1.53h-1.344v2.923c0 .593.013.937.04 1.035a.42.42 0 0 0 .174.241c.091.064.2>...

我试着像fragments['card'].select('svg').clone();那样做,但结果是:TypeError: Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

我也尝试关注fragments['card'].select('svg').toDefs();,但结果是:DOMException: Failed to execute 'appendChild' on 'Node': The new child element contains the parent.

使用snap可以做什么方法?

修改 好像我需要使用:

  Surface.append(fragments['card']);
  const Card = Surface.select('#card');
  Card.toDefs();
  const CardDef = Surface.select('#card');
  CardDef.use().attr({...});

现在问题是为什么这不起作用fragments['card'].select('svg').toDefs();并且上面的代码呢?为什么我不能直接使用fragments['card'].select('svg')

1 个答案:

答案 0 :(得分:1)

一个片段没有Snap方法的概念,所以像clone()这样的方法不起作用。首先,他们需要附加到DOM。此外,片段并不完全在DOM中,因此DOM SVG元素可以使用一些常见的svg方法。

因此像fragment.select('svg')。clone()这样的东西不起作用(因为clone是一个Snap方法)。首先,你需要'Snapify'它(把它变成一个Snap元素,一个围绕svg元素的包装)。

所以你需要做类似以下的事情......首先将它添加到DOM ...

Surface.append( fragment.select('svg') );

现在它在DOM中,你可以Snapify它并克隆它(因为我们现在有了这个元素可用的Snap方法)。

Surface.select('someId').clone();

注意,如果你在某个地方有一个DOM元素,你也可以通过

将它变成一个Snap元素
var snapElement = Snap( someDomElement );

这样可以保持DOM元素不变,但只是在它周围添加一个Snap包装器,并将其作为Snap元素返回。

所以你自己找到了正确的代码,主要答案是你的元素在尝试调用它时(或附加到DOM)时不是Snap元素。

注意:您可以将片段Snapify而不将其添加到DOM中,但它不会为您带来任何新方法,除非它在我认为的主DOM中,但可以方便地存储对元素的引用这将在以后附加。