4

For a web project, I'm using SVG with the svg.js library to make my life easier. The svg.js library works perfectly and generates correct SVG so I'm pretty sure everything is working OK on that front.

For this project, I can refer to a font like this in my CSS file:

@font-face {
    font-family: 'FreeUniversal';
    src: url('../fonts/freeuniversal-regular.ttf');
    font-weight: normal;
    font-style: normal;
}

This font is then picked up correctly and displayed for various elements in my HTML code.

My question is how I can do this in SVG using the svg.js library? I understand I can set the current font and so on, like this:

sCurrentSvgShape.attr({
    'font-family': inFontName,
    'font-size': inFontSize });

And this works for web-safe fonts like "Helvetica" or "Courier" or "Sans". But I want to know how I can set a font family that refers to my specific font file, just as I can in CSS.

I understand CSV has syntax to do this, such as:

<defs>
  <style type="text/css">
   <![CDATA[
    @font-face {
        font-family: Delicious;
        src: url('http://nimbupani.com/demo/svgfonts/delicious-roman.otf');
    }
   ]]>
 </style>
</defs>

So, what's the best way to include this in svg.js? Do I have to create these "defs" nodes manually in some fashion? Is there support from the library to accomplish this?

David van Driessche
  • 6,602
  • 2
  • 28
  • 41

1 Answers1

5

There is no special method to accomplish that in svg.js. However you could make use of the bare element which lets you include non supported elements such as style.

You would use this in the following way:

root.defs().element('style').words(
    '@font-face {' +
       'font-family: Delicious;' +
       'src: url(\'http://nimbupani.com/demo/svgfonts/delicious-roman.otf\');' +
    '}'
)

I did not test it but that should do it.

The second possibility is to invent this style element with the invent method and include this functionality into svg.js yourself.

It would look something like this:

SVG.Style = SVG.invent({
  // Initialize node
  create: 'style'

  // Inherit from
, inherit: SVG.Element

  // Add class methods
, extend: {

    font: function(){

      // code to add a font to the style tag

    }

  , rule: function(){

      // code to add a style rule... whatsoever

    }

  }

, construct: {
    // Create a style element
    style: function() {
      return this.put(new SVG.Style)
    }
  }

})

This would be used like so:

root.defs().style().font('your font method to add a font').rule('add another css rule')
Fuzzyma
  • 7,619
  • 6
  • 28
  • 60
  • That doesn't seem to work, though I did find something that does work by examining your answer. I've tried your first approach which seems to generate the correct CSS insertion when I try it. The font isn't correctly found though. However, if I apply a "style" element to the SVG text element directly and reference "font-family: xxmyfontxx;" in there, it does work, I'm assuming because the browser then picks this up through the CSS rule in my regular CSS file... I'd still like to get this working along the way of what you suggested though - what I'm doing now feels like a hack. – David van Driessche Feb 28 '16 at 12:40
  • I dont know whether you have to include the CDATA stuff you have in your question. Also I dont know if the style tag should be in the defs tag. However: Using css rules in svg is quite common. Maybe you can even write it into your css file – Fuzzyma Feb 28 '16 at 12:47
  • Yeah, I tried it with the CDATA part too but that didn't seem to make any difference. Perhaps I should indeed just give my text a class and have the CSS take care of it; that should work just fine too. Just feels like a cheat not doing everything in SVG, especially knowing that it should work :) Thanks! – David van Driessche Feb 28 '16 at 13:39
  • Jeah - that's annoying. Let me know if you somehow get it to work with svg. It really is more an svg thing in general. Maybe another question would help... – Fuzzyma Feb 28 '16 at 13:47