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

Quick Touch Events

  1. // no scrolling on mobile
  2. document.addEventListener("touchmove", e => e.preventDefault(), {
  3.   passive: false
  4. });
  5.  
  6. // has more than one touch point
  7. const hasTouch =
  8.   navigator.maxTouchPoints != null && navigator.maxTouchPoints > 0;
  9.  
  10. function touchify(e) {
  11.   const touch = [];
  12.   touch.x = touch.y = 0;
  13.  
  14.   if (e.touches != null && e.touches.length > 0) {
  15.     touch.x = e.touches[0].clientX;
  16.     touch.y = e.touches[0].clientY;
  17.     for (let i = 0; i < e.touches.length; i++) {
  18.       touch[i] = e.touches[i];
  19.     }
  20.   } else {
  21.     touch.x = e.clientX;
  22.     touch.y = e.clientY;
  23.     touch[0] = { clientX: e.clientX, clientY: e.clientY };
  24.   }
  25.   return touch;
  26. }
  27.  
  28. let clickOrTouchEnd,
  29.   downOrTouchStart,
  30.   enterOrTouchStart,
  31.   moveOrTouchMove,
  32.   upOrTouchEnd,
  33.   leaveOrTouchEnd;
  34.  
  35. if (hasTouch) {
  36.   clickOrTouchEnd = "touchend";
  37.   downOrTouchStart = "touchstart";
  38.   enterOrTouchStart = "touchstart";
  39.   moveOrTouchMove = "touchmove";
  40.   upOrTouchEnd = "touchend";
  41.   leaveOrTouchEnd = "touchend";
  42. } else {
  43.   clickOrTouchEnd = "click";
  44.   downOrTouchStart = "mousedown";
  45.   enterOrTouchStart = "mouseenter";
  46.   moveOrTouchMove = "mousemove";
  47.   upOrTouchEnd = "mouseup";
  48.   leaveOrTouchEnd = "mouseleave";
  49. }
  50.  
  51. function dot(x, y, radius, color) {
  52.   const el = document.createElement("div");
  53.   const size = `${radius * 2}px`;
  54.   Object.assign(el.style, {
  55.     position: "absolute",
  56.     left: `${x}px`,
  57.     top: `${y}px`,
  58.     width: size,
  59.     height: size,
  60.     transform: `translate(${-radius}px, ${-radius}px)`,
  61.     borderRadius: "50%",
  62.     background: color
  63.   });
  64.   el.classList.add("dot");
  65.   document.body.appendChild(el);
  66.   return el;
  67. }
  68.  
  69. let down = false;
  70. let lastTouch;
  71. document.addEventListener(downOrTouchStart, e => {
  72.   const { x, y } = touchify(e);
  73.   dot(x, y, 30, `rgba(255, 0, 0, 0.2)`);
  74.   down = true;
  75. });
  76.  
  77. document.addEventListener(moveOrTouchMove, e => {
  78.   if (down) {
  79.     const touches = touchify(e);
  80.     // draw more than one touch
  81.     for (let i = 0; i < touches.length; i++) {
  82.       const touch = touches[i];
  83.       dot(touch.clientX, touch.clientY, 10, `rgba(0, 0, 155, 0.2)`);
  84.     }
  85.  
  86.     lastTouch = touches[0];
  87.   }
  88. });
  89.  
  90. document.addEventListener(upOrTouchEnd, e => {
  91.   if (down) {
  92.     dot(lastTouch.clientX, lastTouch.clientY, 20, `rgba(0, 155, 0, 0.2)`);
  93.     down = false;
  94.   }
  95. });

Draw with your mouse by clicking, holding down and dragging…

I often use some variation of this depending on the project… This snippet normalizes touch events in a simple way, prevents scrolling and gives an example of how to handle multi-touch.

You’ll probably want a to use a meta tag like this – for the full effect.

  1. <meta name="viewport" content="width=device-width, initial-scale=1.0">

No Scrolling on Mobile

  1. document.addEventListener('touchmove', 
  2.   e => e.preventDefault(), { passive: false });
  3.   document.body.innerHTML = 'Hi, no page scrolling here...';

It’s common to want to prevent page scrolling on mobile. Here is an easy way to do it.

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.

Print a Tabula Recta (codegolf)

  1. const tabulaRecta = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  2.   .replace(/./g,"$&$'$`\n");
  3.  
  4. const pre = document.createElement('pre');
  5. document.body.appendChild(pre);
  6. pre.innerHTML = tabulaRecta;
  7.  
  8. // technique comes from https://codegolf.stackexchange.com/a/87035/63485

This snippet comes from the the codegolf stackexchange. A little while back a challenge for printing a tabula recta popped up along with a very nice answer from user Neil. Take a look at the answer here.

Shuffle an Array

  1. const nums = [1, 10, 20, 30, 50, 88];
  2. nums.sort(() => Math.random() - 0.5);
  3. console.log(nums);

Common way to shuffle the values in an array.

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