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

Elasticity With Trails

  1. let pointX = pointY = 0;
  2.  
  3. document.addEventListener('touchmove', 
  4.   e => e.preventDefault(), { passive: false });
  5.  
  6. document.addEventListener('mousemove', e => {
  7.   pointX = e.clientX;
  8.   pointY = e.clientY;
  9. });
  10.  
  11. document.addEventListener('touchmove', e => {
  12.   pointX = e.touches[0].clientX;
  13.   pointY = e.touches[0].clientY;
  14. });
  15.  
  16. let el = document.body.appendChild(
  17.   document.createElement`div`
  18. );
  19.  
  20. const size = 20;
  21. const halfSize = size / 2;
  22.  
  23. Object.assign(el.style, {
  24.   position: 'absolute',
  25.   width: `${size}px`,
  26.   height: `${size}px`,
  27.   background: 'red',
  28.   borderRadius: `${size}px`,
  29.   left: 0, top: 0
  30. });
  31.  
  32. let x = vx = y = vy = 0;
  33. const FADE_TIME = 800;
  34. const plotDot = (x, y) => {
  35.   const dot = document.body.appendChild(el.cloneNode());
  36.   const time = 
  37.   dot.style.transform += ' scale(.25)';
  38.   dot.style.transition = `opacity ${FADE_TIME}ms ease-out`;
  39.   window.requestAnimationFrame(() => {
  40.     dot.style.opacity = 0;
  41.     setTimeout(() => dot.parentNode.removeChild(dot), FADE_TIME);
  42.   })
  43. }
  44.  
  45. let ticks = 0;
  46. const loop = () => { 
  47.   vx = ((pointX - x) * .08 + vx) * .95;
  48.   vy = ((pointY - y) * .08 + vy) * .95;
  49.   x += vx;
  50.   y += vy;
  51.  
  52.   if (ticks++ % 2 === 0 && 
  53.     Math.abs(pointX - x) > 1 && 
  54.     Math.abs(pointY - y) > 1) {
  55.       plotDot();
  56.     }
  57.   el.style.transform = `translate(${x - halfSize}px, ${y - halfSize}px)`;
  58.   requestAnimationFrame(loop);
  59. }
  60. loop();
  61.  
  62. const info = document.body.appendChild(
  63.   document.createElement`div`
  64. );
  65. info.innerHTML = 'move mouse or finger left/right/up/down';

This is a variation on yesterdays post. This has elasticity on both axis and draws a trail of dots…

Elasticity

  1. let pointX = pointY = 0;
  2.  
  3. document.addEventListener('mousemove', e => {
  4.   pointX = e.clientX;
  5.   pointY = e.clientY;
  6. });
  7.  
  8. document.addEventListener('touchmove', e => {
  9.   pointX = e.touches[0].clientX
  10.   pointY = e.touches[0].clientY
  11. });
  12.  
  13. let el = document.body.appendChild(
  14.   document.createElement`div`
  15. );
  16.  
  17. const size = 20;
  18. const halfSize = size / 2;
  19.  
  20. Object.assign(el.style, {
  21.   position: 'absolute',
  22.   width: `${size}px`,
  23.   height: `${size}px`,
  24.   background: 'red',
  25.   left: 0, top: 0
  26. })
  27.  
  28. let x = vx = 0;
  29. const loop = () => { 
  30.   vx = ((pointX - x) * .2 + vx) * .79;
  31.   x += vx;
  32.   el.style.transform = `translate(${x - halfSize}px, 50px)`;
  33.   requestAnimationFrame(loop);
  34. }
  35. loop();
  36.  
  37. let info = document.body.appendChild(
  38.   document.createElement`div`
  39. );
  40. info.innerHTML = 'move mouse or finger left/right';

Basic interactive elasticity with mouse or touch

Hacky Polish Notation

  1. const f = (o, ...a) => eval(a.join(o));
  2.  
  3. const polish = eq => eval(
  4.     eq.replace(/\s+/g, ' ')
  5.       .replace(/(\))\s([0-9])/g, '$1,$2')
  6.       .replace(/([0-9]+)[^\)]/g, '$1,')
  7.       .replace(/\(\s?([\+\-\*\\/])/g, 'f(`$1`,')
  8.   );
  9.  
  10. console.log(polish('(* 2 2)'));
  11. console.log(polish('(* 2 2 (+ 3 2 1))'));
  12. console.log(polish('(- 10 3)'));
  13. console.log(polish('(/ (+ 10 10 (* 2 2)) 3)'));

Hacky way to parse polish notation. This uses regular expressions to transform polish notation into javascript that can be run with eval. Just a weird/fun idea…

What is the current element? (document.activeElement)

  1. console.log(document.activeElement);

I use document.activeElement constantly when I do accessibility work (getting things to work with screenreaders like NVDA, JAWS or VoiceOver). document.activeElement contains the current element that is in focus on a page.

You can easily debug it with a live expression in the chrome console:

Here is a small demo to play with – try clicking or tabbing around the buttons and inputs:

  1. const el = document.createElement('el');
  2. el.innerHTML = `
  3.   <button class="one">one</button>
  4.   <button class="two">two</button>
  5.   <button class="three">three</button>
  6.   <button class="four">four</button>
  7.   <hr>
  8.   <input type="text" placeholder="type...">
  9.   <hr>
  10.   <input type="range">
  11. `;
  12. document.body.appendChild(el);
  13.  
  14. let lastActive;
  15. setInterval(() => {
  16.   if (document.activeElement != lastActive) {
  17.     lastActive = document.activeElement;
  18.     console.log(lastActive.outerHTML);
  19.   }
  20.  
  21. // no need to update 60fps
  22. }, 100);

Hijack Focus

  1.  
  2. const el = document.body.appendChild(
  3.   document.createElement('div')
  4. );
  5.  
  6. el.innerHTML = `
  7. <button>one</button>
  8. <button>two</button>
  9. <button>three</button>
  10. `;
  11.  
  12. document.addEventListener('click', e => {
  13.   e.target.focus();
  14. });
  15.  
  16. const origFocus = HTMLElement.prototype.focus
  17. HTMLElement.prototype.focus = function() {
  18.   console.log(this.outerHTML, 'focus was called');
  19.   origFocus.call(this);
  20. };
  21.  
  22. el.firstElementChild.focus();

Easy way to debug many calls to focus.

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