7

Updated question, based on a simpler test case:

I have a website using a <svg> graphic generated by a script. The stuff in the graphic is filled with svg patterns. So far, so good.

I now add a <pattern> element, using Javascript, to the patterns that are already in the graphic. I can easily do that, using methods like createElementNS, setAttribute and appendChild.

SVG pattern elements look like this:

<defs>
<pattern id="stripes" width="6" height="6" patternUnits="userSpaceOnUse">
<svg:path d="M 0 0 L 10 0 L 10 1 L 0 1 Z" fill="red" width="6" height="6" id="stripepimage"></svg:path>
</pattern>
</defs>

and they're used like this:

<path d="..." fill="url(#stripes)" />

Now: using Javascript, or the browser console, I can change a <path>'s fill attribute to use different patterns. That works fine for all the patterns that were in the page from the start, but it does not for patterns added later on. The SVG code itself is fine; saving it in a .svg and opening that up in the same browser shows the new pattern flawlessly.

Why can dynamically generated patterns not be used?

sk29910
  • 2,326
  • 1
  • 18
  • 23
  • this might depend on the version of SVG that your plugin supports. (or that is supported natively in your browser) – Randy Aug 04 '11 at 14:07
  • What depends on that? Whether or not patterns are applied when the elements are created dynamically or loaded from a file? (I'm testing on Chrome and Firefox, and they're pretty much up to date -- and it's an in-house thing, so I don't even care about old IEs). – sk29910 Aug 04 '11 at 14:18
  • well, it's just a comment... i noticed several differences between the Adobe plugin on ie and the built in support on chrome ( which is SVG 1.1 compatible i think ). So one idea would be to try it on the adobe plugin and see it it magically works. – Randy Aug 04 '11 at 15:06
  • Interesting, thanks. We're all on Linux, so I can't easily test that. Just tried in Opera, and it's the same deal. – sk29910 Aug 04 '11 at 15:26
  • I just wrote a simple test case, and it seems as if it's impossible to add a pattern using JS (even though it shows up in the source right away), and then assign it to an object using .setAttribute('fill'). The latter works fine as long as you're dealing with pre-existing patterns. Is there a way to tell the browser to accept all new patterns into its DOM tree? – sk29910 Aug 04 '11 at 16:36
  • Figured it out (see solution) -- thanks for your help still! – sk29910 Aug 04 '11 at 17:59

2 Answers2

8

Firstly, ensure you create an element using the namespaced document.createElementNS

e.g.

document.createElementNS('http://www.w3.org/2000/svg','rect')

Secondly, only a reference within the 'style' attribute seemed to dynamically apply a pattern housed within 'defs'

e.g.

<defs>
    <pattern id="patternTest1" width="10" height="10" patternUnits="userSpaceOnUse">
        <path d="M10,0 L10,10 L0,10" fill="none" stroke="#E9E9E9" stroke-width="1" shape-rendering="crispedges" vector-effect="non-scaling-stroke"/>
    </pattern>
</defs>

<rect id="test" x="10" y="10" width="250" height="250" style="fill: url('#patternTest1');" vector-effect="non-scaling-stroke" stroke-width="1" stroke-dasharray="none" stroke="#000000" />
Steve
  • 3,483
  • 5
  • 21
  • 20
0

Problem solved, this SO question helped me out. I had a typo in my SVG namespace declaration when I used createElementNS, so the pattern and path elements weren't recognized as "the real thing", but just as regular tags.

If you want to use Javascript to manipulate the SVG DOM tree, pay attention to this.

Community
  • 1
  • 1
sk29910
  • 2,326
  • 1
  • 18
  • 23
  • Can you provide the code you used to achieve this please? – Steve Oct 10 '11 at 12:01
  • I don't work there anymore unfortunately and don't have access to the code. I think you had to make sure you create all nodes like this: `document.createElementNS("http://www.w3.org/2000/svg", "svg")` (to get ``) ... I hope that helps? – sk29910 Oct 10 '11 at 23:30