apike.ca

SVG Markers (Scripting)

By mbystedt on Feb 24, 2014, 9:46:46 PM

This page deals with a few extra topics surrounding markers and scripting. First, we'll look at how markers ignore events. We will then use JavaScript to reach into a marker and show that changing it reflects everywhere it was used.

Marker Events

Example 1. Only mousing over the box that contains the line fires the event. (Download)

This example shows that markers are not considered part of the object that uses them. The line has a mouse enter event attached to it but hovering over the marker does nothing. It's only when the area defined by the line is entered does the event fire. This is just a limitation of SVG. If you were hoping to get an event from a marker then you're going to be disappointed.

The SVG viewer will also ignore any JavaScript event code or SMIL animation attached to marker shapes. This is probably desirable unlike the previous point. These behaviours were probably put in to save on memory and processing. In the next part, we will have fun with the fact each marker displayed is really just a reference to the original.

Altering Using JavaScript

Example 2. There is only one marker. Rotating it rotates all the instances. (Download)
<script type="text/ecmascript"><![CDATA[
  var rotAngle = 0;
 
  function rotateFlowers() {
    svgDocument.getElementById("myMarkerPath").setAttribute(
      "transform", "rotate("+ rotAngle +", 100, 100)");
    rotAngle = rotAngle+3;
    setTimeout(rotateFlowers, 100);
  }
]]></script>
...
<defs>
...
  <marker id="myMarker" viewBox="0 0 200 200" refX="100" refY="100" >
    <g id="myMarkerPath">
      <path  d="M50,50 Q-30,100 50,150 100,230 150,150 230,100 150,50 100,-30 50,50" 
        stroke="darkblue" stroke-width="4" fill="url(#myFillGrad)" />
      <line x1="100" y1="20" x2="100" y2="180" stroke="#eee" stroke-width="7px" />
      <line x1="20" y1="100" x2="180" y2="100" stroke="#eee" stroke-width="7px" />
      <circle cx="100" cy="100" r="20" fill="red" />
    </g>
  </marker>
</defs>
...
<line x1="40" y1="400" x2="40" y2="200" stroke="green" stroke-width="30" marker-end="url(#myMarker)"/>
<line x1="80" y1="400" x2="82" y2="160" stroke="green" stroke-width="30" marker-end="url(#myMarker)"/>
<line x1="120" y1="400" x2="140" y2="200" stroke="green" stroke-width="30" marker-end="url(#myMarker)"/>
Code 1. The JavaScript alters the marker and all the flowers turn.

You can reference the contents of a pattern and change it using Javascript. There is no way to change only one instance of a marker. If you change the marker every instance will update.

Related Topics