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

Little Galaxy ES5

  1. var canvas = document.createElement('canvas'), 
  2.     c = canvas.getContext('2d'), 
  3.     SIZE = 350;
  4.  
  5. canvas.width = SIZE;
  6. canvas.height = SIZE;
  7.  
  8. document.body.appendChild(canvas);
  9.  
  10. c.fillStyle = 'black';
  11. c.fillRect(0, 0, SIZE, SIZE);
  12.  
  13. c.fillStyle = 'white';
  14.  
  15. var spa = function(ts) {
  16.   var r = 0, t =  0;
  17.   var jitterX, jitterY, jitterT, jitterR;
  18.   for (var i = 0; i < 100; i += 0.5) {
  19.     t = ts + i / 15;
  20.     r = i;
  21.     jitterR = 5 + i / 5;
  22.     jitterT = Math.random() * 2 * Math.PI;
  23.     jitterX = Math.random() * jitterR * Math.sin(jitterT);
  24.     jitterY = Math.random() * jitterR * Math.cos(jitterT);
  25.     c.fillStyle = `hsl(${t / Math.PI * 180}deg, 50%, 50%)`;
  26.     c.fillRect(
  27.       SIZE / 2 + r * Math.cos(t) + jitterX,
  28.       SIZE / 2 + r * Math.sin(t) + jitterY, 
  29.       3, 3
  30.     );
  31.   }
  32. }
  33.  
  34. spa(0);
  35. spa(Math.PI);

I made this in response to a question from a friend of mine a few years back…

Object Key Order and Reflect.ownKeys

  1. const obj = { 11: 'eleven', 23: 'twenty-three', 1: 'one', 2: 'two', '-1': 'negative 1' };
  2.  
  3. console.log(Reflect.ownKeys(obj))

I noticed that for in.. over an object was giving me weirdly consistent results across all browsers the other day and stumbled upon this.

Great news, but it’s Reflect.ownKeys for me… now that IE11 is dying/dead.

selectAll Thoughts

  1. const lookup = new WeakMap() 
  2.  
  3. let id = 0;
  4.  
  5. export const els = selectAll(document.body)
  6. export const parentOf = el => lookup.get(el)
  7.  
  8. export function selectAll(parent) {
  9.   const els = { id, el: parent, all: {} }
  10.   const allEls = [...parent.querySelectorAll('*')]
  11.  
  12.   id++
  13.  
  14.   for (let i in allEls) {
  15.     const el = allEls[i]
  16.  
  17.     // any element can lookup `els`
  18.     lookup.set(el, els)
  19.  
  20.     const tag = el.tagName.toLowerCase()
  21.  
  22.     if (el.id) {
  23.       els[el.id] = el
  24.  
  25.       tag === 'template' &&
  26.         (els[el.id + 'Tmpl'] = () => {
  27.           const instanceEl = el.content
  28.             .cloneNode(true)
  29.             .firstElementChild
  30.           return selectAll(
  31.             instanceEl
  32.           )
  33.         })
  34.     }
  35.  
  36.     if (el.classList.length > 0) {
  37.       const name = el.classList[0]
  38.  
  39.       if (!els[name]) { 
  40.         els[name] = el
  41.         els.all[name] = [el]
  42.       } else {
  43.         els.all[name].push(el)
  44.       }
  45.     }
  46.   }
  47.   return els;
  48. }

Whenever I code a vanilla gui for some personal project/experiment I write some variation of this. I did this one a few days back to see how it would work with template tags.

// tricks // ui

xPath contains (document.evaulate)

  1. // hack to shove some html on the page since snippet.zone
  2. // quick editor does not yet support HTML :P
  3. document.body.innerHTML += `
  4.   <p>This is some text to search...</p>
  5.   <p>Here are some random words "Robot, Cat, Swan, Shadow"...</p>
  6.   <button>Say Hello Robot</button>
  7. `;
  8.  
  9. ///////////
  10.  
  11. // find elements with the word `search`
  12. let els = document.evaluate(
  13.   "//p[contains(., 'search')]",
  14.   document,
  15.   null,
  16.   XPathResult.ANY_TYPE,
  17.   null
  18. );
  19. let el;
  20. while (el = els.iterateNext()) {
  21.   console.log('match "search"', el);
  22. }
  23.  
  24. els = document.evaluate(
  25.   "//body/*[contains(., 'Robot')]",
  26.   document,
  27.   null,
  28.   XPathResult.ANY_TYPE,
  29.   null
  30. );
  31. while (el = els.iterateNext()) {
  32.   console.log('match "Robot"', el);
  33. }

Now that IE is almost dead… we can use xPath – take a look at your console

xPath and svg

  1. // hack to shove some html on the page since snippet.zone
  2. // quick editor does not yet suppor HTML :P
  3. document.body.innerHTML += `
  4.   <svg style="overflow:visible">
  5.   <rect x="10" y="10" fill="red" width="30" height="10" />
  6.   <rect x="10" y="20" fill="blue" width="30" height="10" />
  7.   <rect x="10" y="30" fill="purple" width="30" height="10" />
  8.   </svg>
  9. `;
  10.  
  11. const svgPrefix = pre => pre === 'svg' && 'http://www.w3.org/2000/svg';
  12.  
  13. // https://stackoverflow.com/questions/31162358/extract-svg-element-by-using-document-evaluate
  14. let els = document.evaluate(
  15.   '//svg:svg/*[@fill="blue"]',
  16.   document,
  17.   svgPrefix,
  18.   XPathResult.ANY_TYPE,
  19.   null
  20. );
  21.  
  22. const results = [];
  23. while ((el = els.iterateNext())) {
  24.   // save results to avoid mutation error
  25.   results.push(el);
  26. }
  27. results[0].x.baseVal.value = 50;
  28. results[0].setAttribute('stroke', 'orange');
  29. results[0].setAttribute('stroke-width', 2);

Now that IE 11 is almost dead… we can use document.evaluate – I knew there would be some trick to get it to work on svg… Found the answer from user Martin Honnen on stackoverflow – very cool.

Of course this one can be done with document.querySelectorAll('*[fill="blue"]') – but xPath can do some other stuff that css selectors can’t exactly do yet…

// svg // xPath
snippet.zone ~ 2021-24 /// {s/z}