# spirograph

This example is based on Orbital Resonance in SVG (opens new window) built for Dudley Storey (opens new window). In this case we have adapted his creation using gySVG and simplifying some elements.

edit in codepen.io (opens new window)

We will now explain step by step how to create a dynamic SVG of this type.

# Import gySVG

The first step, if we haven't already done so, is to import the gySVG library. In our case, we've chosen to include the code within a script type=module and we'll use the import expression.

see: load gySVG

# Create the SVG

To create the graph we are going to use gySVG() and we are going to configure the viewBox.

see: SVG Element, .viewBox, .attachTo

# SVG background color

The style used need a black background and this is a property of SVG:

# The circle guides

We put two circles as guide for the building process visualization. It's simple with .add('circle')

# Group for lines

For an easy configuration we will put all lines generated into the building process into a group create with add('g'). This group has a stroke configuration for all lines includes inside:

# Build the pattern

Now, we will create a setInterval() and create a lot of lines between the to circle guides. This guides rotate into a circle with different speed, and as result, we obtain a magical image.

# Re build when click the image

To complete our example we will add a simple functionality: re-build the image if the user clicks on the SVG. For this we need to capture the event click and set the style to show the hand cursor indicating that it is a clickable element.

# The complete code

If we put all these steps together this is the example's code:

import gySVG from 'https://cdn.graphery.online/0.1.5/svg/module/index.js';

const svg = gySVG ().viewBox (0, 0, 500, 500)
  .style.backgroundColor ('#000')
  .style.cursor ('pointer')
  .addEventListener ('click', start);
const p1    = svg.add ('circle').cx (250).cy (20).r (5).style.fill ('white');
const p2    = svg.add ('circle').cx (250).cy (100).r (5).style.fill ('white');
const lines = svg.add ('g').style.strokeWidth (1);

svg.attachTo ('#content');

let interval = 0;
start ();
function start () {
  let i = 0;
  p2.style.display ('');
  p1.style.display ('');
  lines.content ('');
  clearInterval (interval);
  interval = setInterval (function () {
    i += 5;
    if (i >= (360 * 8) + 5) {
      clearInterval (interval);
      p2.style.display ('none');
      p1.style.display ('none');
    }
    p1.transform ('rotate(' + i + ' ' + 250 + ' ' + 250 + ')');
    p2.transform ('rotate(' + i / (8 / 13) + ' ' + 250 + ' ' + 250 + ')');
    lines.add ('line')
      .x1 (Math.cos (((i - 90) * Math.PI / 180)) * 230 + 250)
      .y1 (Math.sin (((i - 90) * Math.PI / 180)) * 230 + 250)
      .x2 (Math.cos (((i / (8 / 13)) - 90) * Math.PI / 180) * 150 + 250)
      .y2 (Math.sin (((i / (8 / 13)) - 90) * Math.PI / 180) * 150 + 250)
      .stroke ('hsla(' + i + ', 50%, 50%, 0.5)');
  }, 30);
}