)
}
}
)
(
}
{
)
)
(
)
(
(
{
}
)
(
)
}
)
)
{
(
(
)
)
}
)
(
}

Drawing Gears With SVG

  1. const el = document.body.appendChild(
  2.   document.createElement('div'));
  3.  
  4. el.innerHTML = `
  5.   <svg id="svg" width="100%" height="100%" viewBox="0 0 550 496">
  6.     <path id='path' d="M 10 10 L 100 100" stroke="black" fill='none' vector-effect="non-scaling-stroke"/>
  7.   </svg>
  8.   <style>
  9.     svg, div, body, html {
  10.       overflow: visible; 
  11.       height: 100%; 
  12.       width: 100%;
  13.       margin: 0; padding: 0;
  14.     }
  15.   </style>
  16.   `;
  17.  
  18. // a variation on something from my old 
  19. // site https://actionsnippet.com/?p=1175
  20.  
  21. const TWO_PI = Math.PI * 2;
  22. let cmds = '';
  23.  
  24. // x, y, max radius, notch number
  25. drawVerts(calcGear(200, 200, 50, 6));
  26. drawVerts(calcGear(400, 200, 30, 3));
  27. drawVerts(calcGear(300, 350, 30, 20));
  28. drawVerts(calcGear(400, 400, 30, 2));
  29. dotVerts(drawVerts(calcGear(150, 400, 30, 6)));
  30.  
  31. // `<path id=...` becomes a global o_Ö
  32. window.path.setAttribute('d', cmds);
  33.  
  34. function calcGear(x, y, maxRad, notches) {
  35.   let verts = [],
  36.       step = TWO_PI / (notches * 8),
  37.       mod = 0, r;
  38.   for (let i = 0; i <= TWO_PI; i += step) {
  39.     r = (parseInt(mod) % 2 + 1) * maxRad;
  40.     mod += .25;
  41.     verts.push(x + r * Math.cos(i));
  42.     verts.push(y + r * Math.sin(i));
  43.   }
  44.   return verts;
  45. }
  46.   
  47. function drawVerts(verts) {
  48.   cmds += `M ${verts[0]} ${verts[1]} L`;
  49.     for (let i = 2; i < verts.length; i += 2) {
  50.     cmds += ` ${verts[i]} ${verts[i + 1]} `
  51.     }
  52.   cmds += 'z ';
  53.   return verts;
  54. }
  55.  
  56. function dotVerts(verts, rad = 3) {
  57.   let dots = '';
  58.   for (let i = 2; i < verts.length; i+=2) {
  59.     dots += `
  60.       <circle 
  61.         cx="${verts[i]}" cy="${verts[i + 1]}"
  62.         r="${rad}"
  63.         fill="red" />
  64.     `
  65.   }
  66.   // another global o_Ö 
  67.   window.svg.innerHTML += dots;
  68. }

Using yesterdays technique, this is a variation of an old snippet from ActionSnippet.com

Quick SVG

  1. const el = document.body.appendChild(
  2.     document.createElement('div'));
  3. el.innerHTML = `<svg style='overlow:visible'>
  4.   <circle cx="100" cy="20" r="20" fill="red" />
  5.   <rect x="100" y="60" width="20" height="20" fill="blue" />
  6. </svg>`;

Defining SVG like this in a template string is a fast and powerful way to start doing SVG that is controlled or generated by JavaScript. Here is another example:

  1. const scribble = document.body.appendChild(
  2.     document.createElement('div'));
  3. const d = (iter = 30) => {
  4.   // make sure the iter is odd
  5.   if (iter % 2 == 0) iter += 1;
  6.   // random cubic beziér
  7.   let path = 'M ';
  8.   for (let i = 0; i < iter; i++) {
  9.     const cmd = i == 1 ? 'C ' : ' '
  10.     path += cmd + Math.random() * 200 + ' ' + Math.random() * 200;
  11.   }
  12.   return path + 'z';
  13. }
  14. scribble.innerHTML = `<svg style='overlow:visible' viewBox="0 0 200 200">
  15.   <path d="${d()}" 
  16.     stroke="#295896" 
  17.     stroke-width="3"
  18.     fill="#ccc" 
  19.     fill-rule="even-odd"
  20.     vector-effect="non-scaling-stroke" />
  21. </svg>
  22. <style>
  23.   svg, div, body, html {
  24.     overflow: visible; 
  25.     height: 100%; 
  26.     width: 100%;
  27.     margin: 0; padding: 0;
  28.   }
  29. </style>
  30. `;

You’ll notice a somewhat hacky style tag as well… this is used to quickly fill the page with the SVG.

Convert an Image to dataUri

  1. function toDataUri(img, scalar = 1) {
  2.   const canvas = document.createElement('canvas');
  3.   canvas.width = img.width * scalar;
  4.   canvas.height = img.height * scalar;
  5.   canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
  6.   return canvas.toDataURL('image/png');
  7. }
  8.  
  9. const img = new Image();
  10. img.crossOrigin = 'Anonymous';
  11. img.addEventListener('load', () => {
  12.   const thumb = new Image();
  13.   // use the data URI as the source
  14.   thumb.src = toDataUri(img, .3);
  15.   document.body.appendChild(thumb);
  16. });
  17. img.src = 'https://zevanrosser.com/fotoda/slide-shot-9.jpg';

Load an image and convert it to a data URI.

Make a Debugging Dot

  1. function dot(x, y, radius, color) {
  2.   const el = document.createElement('div');
  3.   const size = `${radius * 2}px`;
  4.   Object.assign(el.style, {
  5.     position: 'absolute', 
  6.     left: `${x}px`,
  7.     top: `${y}px`,
  8.     width: size,
  9.     height: size,
  10.     transform: `translate(${-radius}px, ${-radius}px)`,
  11.     borderRadius: '50%',
  12.     background: color
  13.   });
  14.   el.classList.add('dot');
  15.   document.body.appendChild(el);
  16.   return el;
  17. }
  18.  
  19. dot(100, 100, 10, 'red');
  20. dot(200, 100, 5, 'blue');
  21.  
  22. for (let i = 0; i < 20; i++) {
  23.   dot(20 + i * 12, 200, 5, `hsl(${i * 10}deg, 60%, 50%)`)
  24. }

Draw a dot – good for visualizing things when doing animation and positioning logic.

Draw a Spiral with Resize

  1. const canvas = document.body.appendChild(
  2.   document.createElement('canvas')
  3. );
  4. const c = canvas.getContext('2d');
  5.  
  6. function resize() {
  7.   canvas.width = window.innerWidth;
  8.   canvas.height = window.innerHeight;
  9.   draw();
  10. }
  11.  
  12. function draw() {
  13.   c.clearRect(0, 0, canvas.width, canvas.height);
  14.   c.fillStyle = 'blue';
  15.  
  16.   const iter = 300,
  17.         halfWidth = window.innerWidth / 2,
  18.         halfHeight = window.innerHeight / 2;
  19.   let rad = 0, theta = 0, x, y;
  20.   for (let i = 0; i < iter; i++) {
  21.     x = halfWidth + rad * Math.cos(theta);
  22.     y = halfHeight + rad * Math.sin(theta);
  23.     c.fillRect(x, y, 5, 5);
  24.     rad += Math.min(window.innerWidth, window.innerHeight) * 0.0015;
  25.     theta += .1;
  26.   }
  27. }
  28.  
  29. resize();
  30. window.addEventListener('resize', resize);

Expanding on yesterdays post, this draws a resizable sprial on a canvas.

snippet.zone /// {s/z}