LearningSVG

From HerzbubeWiki
Jump to: navigation, search

This page is about my novice steps with Scalable Vector Graphics (SVG). Since SVG can be embedded into HTML documents it can even be considered a web technology, or web API. Consequently this page also has information about SVG's ties to HTML and CSS.

A separate page on this wiki has information about Inkscape, an open source vector graphics editor.


References


Shapes

Rectangle

Example for drawing a rectangle:

<rect x="50" y="20" rx="20" ry="20" width="150" height="150"
      style="fill: blue; stroke: pink; stroke-width: 5; fill-opacity: 0.1; stroke-opacity: 0.9;" />

Notes:

  • x/y define the upper-left corner of the rectangle
  • width/height define the dimensions of the rectangle
  • rx/ry (optional) define how rounded corners are


Circle and ellipse

Example for drawing a circle and an ellipse:

<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
<ellipse cx="200" cy="80" rx="100" ry="50" style="fill: yellow; stroke: purple; stroke-width: 2;" />

Notes:

  • cx/cy define the center of the circle or ellipse. The default is 0/0.
  • r defines the radius of the circle
  • rx/ry define the horizontal/vertical radius of the ellipse


Line

Example for drawing a line:

<line x1="0" y1="0" x2="200" y2="200" style="stroke: rgb(255,0,0); stroke-width: 2;" />

Notes:

  • x1/y1 define the starting point of the line
  • x2/y2 define the end point of the line


Polyline

Example for drawing a polyline:

<polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160"
          style="fill: white; stroke: red; stroke-width: 4;" />

Notes:

  • The value of the points attribute consists of a series of x/y coordinates that define the polyline points. TODO: Is there a minimum number of points that have to be specified? It would be logical if at least three points had to be specified, because two points only are a regular line.
  • The order in which points are defined is important: It defines the order in which the lines that form the polyline are drawn.
  • The path drawn by a polyline is usually open, unless you explicitly specify points that form a closed path.


Polygon

Examples for drawing a polygon:

<polygon points="200,10 250,190 160,210"
         style="fill: lime; stroke: purple; stroke-width: 1;" />
<polygon points="100,10 40,198 190,78 10,78 160,198"
         style="fill: lime; stroke: purple; stroke-width: 5; fill-rule: nonzero;" />

Notes:

  • The value of the points attribute consists of a series of x/y coordinates that define the polygon points. The minimum polygon is a triangle, so at least three points must be specified.
  • The order in which points are defined is important: It defines the order in which the lines that form the polygon are drawn. This can be important when you have to define a fill rule.
  • A polygon is always closed, i.e. a line is implicitly drawn from the last point to the first point.


Path

In the previous section we saw a number of elements for predefines shapes. However, the most generic of all drawing constructs are paths (<path> element). These are used to draw arbitrary things.

TODO: Add examples.


Text

Examples for drawing a text:

<text x="0" y="15" fill="red">Hello world</text>
<text x="0" y="15" fill="red" transform="rotate(30 20,40)">Hello world</text>
<text x="0" y="15" fill="red">Hello world
  <tspan x="0" y="40">First line</tspan>
  <tspan x="0" y="65">Second line</tspan>
</text>
<a xlink:href="https://example.com/" target="_blank">
  <text x="0" y="15" fill="red">Hello world</text>
</a>

Notes:

  • x/y defines the upper/left corner where the text begins
  • The tspan element can be used to define several sub-groups of text, each with its individual set of properties
  • TODO: What about fonts?


Units

SVG units are the same as in CSS 2. Here's a short overview, a slightly more informative list is available on the LearningCSS page on this wiki. See the SVG specs for the ultimate reference.

  • Absolute units: pt, pc, cm, mm, in.
  • Relative units: em, ex, px.
  • Percentages: Relative to the viewport size.

If the unit is omitted, it defaults to px.


Here's a quote from the SVG specs on the use of px (emphasis is mine):

One px unit is defined to be equal to one user unit. Thus, a length of "5px" is the same as a length of "5".

Note that at initialization, a user unit in the the initial coordinate system is equivalenced to the parent environment's notion of a px unit. Thus, in the the initial coordinate system, because the user coordinate system aligns exactly with the parent's coordinate system, and because often the parent's coordinate system aligns with the device pixel grid, "5px" might actually map to 5 devices pixels. However, if there are any coordinate system transformation due to the use of ‘transform’ or ‘viewBox’ attributes, because "5px" maps to 5 user units and because the coordinate system transformations have resulted in a revised user coordinate system, "5px" likely will not map to 5 device pixels. As a result, in most circumstances, "px" units will not map to the device pixel grid.


Stroke and fill

A shape or path is made up from lines. The way how those lines are drawn is defined by various properties:

  • Stroke color: What color does the line have? This is defined by the stroke property.
  • Stroke width: How thick is the line? This is defined by the stroke-width property.
  • Stroke dash: Is the line solid or dashed, and how do the dashes look? This is defined by the stroke-dasharray property.
  • Stroke opacity: How transparent is the line? This is defined by the stroke-opacity property.
  • Stroke linecap: How does the end of a line look like (applies to open paths only)? This is defined by the stroke-linecap property.


The "fill" of a shape or path defines how the inside of the shape looks like. Various properties define the fill:

  • Fill color: What color does the fill have? This is defined by the fill property.
  • Fill rule: Which parts of the shape or path are filled? This is defined by the fill-rule property. Possible values are nonzero and evenodd. TODO: How does this work?


General notes:

  • Stroke and fill properties can be specified in two ways:
    • CSS rules. Example: <rect style="stroke: blue;" ... />
    • Attributes. Example: <rect stroke="blue" ... />
  • Color property values can be pre-defined color names (e.g. blue) or RGB values (e.g. rgb(0, 0, 0)).
  • The opacity property can be used to control the opacity of the entire shape or path, i.e. both stroke and fill.
  • Opacity property values range from 0 (transparent) to 1 (opaque).


Object groups

SVG objects can be grouped with the <g> element.

TODO: Write more.


Filters

An SVG filter is a collection of SVG filter primitives.

  • In terms of SVG markup, the SVG element <filter> is composed of 0-n <fe...> elements. Each SVG filter primitive has its own dedicated element with a name prefixed by "fe" (probably an abbreviation of "filter effect"), e.g. <feGaussianBlur>.
  • The SVG element <filter> also has an attribute id which is used to reference the filter.
  • When an element being drawn on the canvas references an SVG filter via the filter's id, the filter as a whole is applied to the element being drawn - meaning all SVG filter primitives that the filter is composed of are applied, according to the definition of the filter.
  • An SVG filter can be applied to individual SVG objects, but also to a group of SVG objects.
  • An SVG object, or group of objects, can reference only one SVG filter.


TODO: Write details.


Filters and CSS

CSS can be used to apply filters. TODO: Add more information how this works exactly. Is it possible to apply the filter to normal HTML elements?

Example:

----- the.svg -----
<svg ...>
  [...]
  <filter id="fooFilter" >
    [...]
  </filter> 
</svg>

----- the.css -----
/* TODO: Not sure what #bar can refer to. */
#bar {
  filter: url(#fooFilter);
}


Blur effects

TODO Write more


Drop shadows

TODO Write more


Gradients

TODO Write more


Symbols

SVG symbols use the <symbol> element to define template objects which can be instantiated by a <use> element.

TODO Write more


SVG / HTML integration

SVG as web API

SVG is similar to the Canvas web API in that it provides functions for drawing. Unlike Canvas, however, the elements in an SVG image are available via the DOM.

General SVG support is available in all modern browser, even Internet Explorer (since 9.0). However, a particular SVG feature may not be supported by a given browser version.


Displaying an SVG

An SVG can be embedded directly in the HTML document by using the svg element:

<svg width="100" height="100">
  <!-- Add SVG content here -->
</svg>


If the SVG is in an external file you can reference it in an img element:

<img src="foo.svg" ...>


Pretty obvious, but still worth mentioning: CSS can also be used:

body {
  background: url(foo.svg);
  /* This is necessary to scale the SVG image. If omitted the SVG's canvas size is used. */
  background-size: ...;
}


SVG and CSS

SVG elements can be styled with CSS just like any other HTML elements. However, the CSS properties used for SVG styling are usually different from those used for HTML styling. Example: You control the background of an SVG element with the fill property, not with the background-color propery.


You can use CSS selectors to select SVG elements in the same way that you would to select HTML elements. Notably, SVG elements can have id and class attributes just like normal HTML elements.


The Raphaël library

The Raphaël library is a JavaScript library that provides an API to create and manipulate SVG drawings.

URL = http://raphaeljs.com/

TODO: Provide at least a few details.


SVG sprites

SVG sprites are, to my understanding, SVG drawings that are defined once and then reused many times on a website, potentially across many different pages.


Sprite definition

An SVG sprite uses the <symbol> element, roughly like this:

<symbol id="foo" class="hidden">
  [...]
</symbol>`

Notes:

  • Each sprite needs to have a unique id.
  • The hidden class will be explained in a moment.


When you have multiple sprites you can place each one in its own SVG definition, or you can lump them together in a single SVG definition using the <defs> element. This roughly looks like this:

<!-- Single sprite in a file -->
<svg>
  <symbol id="foo">
    [...]
  </symbol>
</svg>

<!-- Multiple sprites in a file -->
<svg>
  <defs>
    <symbol id="foo">
      [...]
    </symbol>
    <symbol id="bar">
      [...]
    </symbol>
    
    [...]

  </defs>
</svg>


Including the sprite definition in HTML

In the HTML document you inline the definitions of all sprites you want to use at the beginning of the body. Here it is usually more convenient to have the sprites lumped together in a single <svg> element:

[...]
<body>
  <svg><defs>[...]</defs></svg>
  [...]
</body>
[...]

Since you don't want to actually display the sprites at the beginning of the body you add a CSS rule that hides the sprites based on the class hidden.


Use sprite in HTML

When you want to use a sprite you reference it like this:

<svg class="icon foo">
  <use xlink:href="#foo"></use>
</svg>


To style the actually used sprites (not the definitions, these are all hidden) with CSS you use class-based rules:

  • To style all sprites you use a generic class, in the example above the class icon.
  • To style an individual sprite you use the class that identifies that sprite, in the example above the class foo.