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

Short Floor (to Integer)

  1. console.log(~~6.62606889);
  2. console.log(0|6.62606889);
  3. console.log(0^6.62606889);
  4.  
  5. console.log(Math.floor(6.62606889));
  6. console.log(parseInt(6.62606889,10));

A few different ways to get rid of decimal values… turning a float into an int.

Make a Grid

  1. const cellSize = 25;
  2. const cols = 10;
  3. const rows = 20;
  4.  
  5. function makeDot(x, y) {
  6.   const dot = document.body.appendChild(
  7.     document.createElement('div')
  8.   );
  9.  
  10.   dot.classList.add('cell');
  11.  
  12.   Object.assign(dot.style, {
  13.     position: 'absolute',
  14.     left: `${x}px`,
  15.     top: `${y}px`,
  16.     width: `${cellSize}px`,
  17.     height: `${cellSize}px`,
  18.     outline: '1px solid black',
  19.     cursor: 'pointer',
  20.     background: 'gray'
  21.   });
  22.  
  23.   return dot;
  24. }
  25.  
  26. for (let y = 0; y < rows; y++) {
  27.   for (let x = 0; x < cols; x++) {
  28.     makeDot(x * cellSize, y * cellSize);
  29.   }
  30. }
  31.  
  32. // make a cell red when it is rolled over
  33. document.addEventListener('mouseover', e => {
  34.   if (e.target.classList.contains('cell')) {
  35.     e.target.style.background = 'red';
  36.   }
  37. });

Here is a simple example for arranging divs in a grid.

// css // dom // javascript // math // tricks // ui

Smooth Bezier on Canvas

  1. const canvas = document.createElement('canvas');
  2. const c = canvas.getContext('2d');
  3.  
  4. document.body.appendChild(canvas);
  5.  
  6. function draw() {
  7.   canvas.width = window.innerWidth;
  8.   canvas.height = window.innerHeight;
  9.   c.fillStyle = 'gray';
  10.   c.fillRect(0, 0, canvas.width, canvas.height);
  11.  
  12.   c.strokeStyle = 'white';
  13.   c.lineWidth = 2;
  14.  
  15.   c.beginPath();
  16.   c.moveTo(0, 0);
  17.   bezierSkin([10, 10, 210, 10, 10, 300, 210, 300], false);
  18.   bezierSkin([200, 10, 330, 10, 250, 300]);
  19.   bezierSkin(
  20.     Array(30)
  21.       .fill(0)
  22.       .map((a, b) => (b % 2 == 0) * 300 + Math.random() * 300)
  23.   );
  24.   c.stroke();
  25. }
  26. window.addEventListener('resize', draw);
  27. draw();
  28.  
  29. // array of xy coords, closed boolean
  30. function bezierSkin(bez, closed = true) {
  31.   const avg = calcAvgs(bez);
  32.   const leng = bez.length;
  33.   let i, n;
  34.  
  35.   if (closed) {
  36.     c.moveTo(avg[0], avg[1]);
  37.     for (i = 2; i < leng; i += 2) {
  38.       n = i + 1;
  39.       c.quadraticCurveTo(bez[i], bez[n], avg[i], avg[n]);
  40.     }
  41.     c.quadraticCurveTo(bez[0], bez[1], avg[0], avg[1]);
  42.   } else {
  43.     c.moveTo(bez[0], bez[1]);
  44.     c.lineTo(avg[0], avg[1]);
  45.     for (i = 2; i < leng - 2; i += 2) {
  46.       n = i + 1;
  47.       c.quadraticCurveTo(bez[i], bez[n], avg[i], avg[n]);
  48.     }
  49.     c.lineTo(bez[leng - 2], bez[leng - 1]);
  50.   }
  51. }
  52.  
  53. // create anchor points by averaging the control points
  54. function calcAvgs(p) {
  55.   const avg = [];
  56.   const leng = p.length;
  57.   let prev;
  58.   for (var i = 2; i < leng; i++) {
  59.     prev = i - 2;
  60.     avg.push((p[prev] + p[i]) / 2);
  61.   }
  62.   // close
  63.   avg.push((p[0] + p[leng - 2]) / 2);
  64.   avg.push((p[1] + p[leng - 1]) / 2);
  65.   return avg;
  66. }

Being able to draw smooth lines that connect arbitrary points is something that I find myself needing very frequently. This is a port of an old old snippet of mine that does just that. By averaging control points of a quadratic bezier curve we ensure that our resulting Bezier curves are always smooth.

It would be very cool if html5 canvas implemented the Catmull Rom Spline but it unfortunately does not. The wonderful Raphael library used to have support for it.

Distance Between Two Points (SVG)

  1. const dist = (x1, y1, x2, y2) => 
  2.   Math.sqrt(
  3.     (x1 - x2) ** 2 + 
  4.     (y1 - y2) ** 2);
  5.  
  6. const el = document.body.appendChild(
  7.   document.createElement('div')
  8. );
  9.  
  10. el.innerHTML = `
  11.   <svg style="overflow:visible;">
  12.     <circle id="circA" cx="150" cy="100" r="50" fill="gray" />
  13.     <circle id="circB" cx="150" cy="200" r="50" fill="blue" />
  14.     <text id="text" dy="20" dx="20">move mouse</text>
  15.   </svg>
  16.   <style>
  17.     body, html, svg {
  18.       width: 100%;
  19.       height: 100%;
  20.     }
  21.   </style>
  22. `;
  23.  
  24. function touch(e) {
  25.   const touches = e.touches;
  26.   let x, y;
  27.   if (touches != null && touches.length > 0) {
  28.     x = touches[0].clientX;
  29.     y = touches[0].clientY;
  30.   } else {
  31.     x = e.clientX;
  32.     y = e.clientY;
  33.   }
  34.   return { x, y };
  35. }
  36.  
  37. const hasTouch = navigator.maxTouchPoints > 0;
  38. const move = hasTouch ? 'touchmove' : 'mousemove';
  39. document.addEventListener(move, e => {
  40.   const { x, y } = touch(e);
  41.  
  42.   // using global ids :D
  43.   circB.cx.baseVal.value = x;
  44.   circB.cy.baseVal.value = y;
  45.  
  46.   const distance = dist(
  47.     circA.cx.baseVal.value, 
  48.     circA.cy.baseVal.value, x, y
  49.   );
  50.   text.innerHTML = 'move mouse, distance: ' + distance;
  51.  
  52.   circA.r.baseVal.value = distance - circB.r.baseVal.value;
  53. });

This snippet shows how to calculate the distance between two points. The dist function uses the pythagorean theorem:

  1. const dist = (x1, y1, x2, y2) => 
  2.   Math.sqrt(
  3.     (x1 - x2) ** 2 + 
  4.     (y1 - y2) ** 2);
// dom // graphics // javascript // math // svg

Creative Coding Auto-Painting

  1. Object.getOwnPropertyNames(Math).map(i => (this[i] = Math[i]))
  2. ;((
  3.   width = innerWidth * 2,
  4.   height = innerHeight * 2,
  5.   cnv = document.body.appendChild(
  6.     Object.assign(document.createElement('canvas'), {
  7.       width,
  8.       height
  9.     })
  10.   ),
  11.   c = cnv.getContext('2d'),
  12.   r = (n = 1) => Math.random() * n,
  13.   NUM = 50,
  14.   f = () => ({
  15.     ax: r(width),
  16.     ay: r(height),
  17.     x: 0,
  18.     y: 0,
  19.     T: r(9),
  20.     R: r(innerWidth * 0.8) + 40,
  21.     t: r(6),
  22.     C: round(r(255)),
  23.     m: r(5) + 1
  24.   }),
  25.   cs,
  26.   sn,
  27.   dx,
  28.   dy,
  29.   ns = [...Array(NUM)].map(f)
  30. ) => {
  31.   Object.assign(cnv.style, {
  32.     transformOrigin: '0 0',
  33.     transform: 'scale(.5)'
  34.   })
  35.   Object.assign(document.body.style, {
  36.     margin: 0,
  37.     padding: 0
  38.   })
  39.  
  40.   const clear = () => {
  41.     c.fillStyle = '#666668'
  42.     c.fillRect(0, 0, width, height)
  43.     c.globalAlpha = 0.5
  44.   }
  45.  
  46.   onresize = () => {
  47.     width = cnv.width = innerWidth * 2
  48.     height = cnv.height = innerHeight * 2
  49.     clear()
  50.   }
  51.  
  52.   clear()
  53.  
  54.   setInterval(() => {
  55.     for (i = 0; i < 30; i++) {
  56.       ns.map((n, i) => {
  57.         with (n) {
  58.           x = ax + R * cos(t)
  59.           y = ay + R * sin(t) * pow(sin(t * 0.5), m)
  60.           c.fillStyle = `rgba(${C},${C},${C},.02)`
  61.           ;(cs = cos(T)), (sn = sin(T)), (dx = x - ax), (dy = y - ay)
  62.           c.fillRect(cs * dx - sn * dy + ax, sn * dx + cs * dy + ay, 50, 50)
  63.           t += 0.1
  64.           R -= 0.01
  65.           if (R < 5) ns[i] = f()
  66.         }
  67.       })
  68.     }
  69.   }, 16)
  70. })()

Speed coded semi-golfed canvas texture. Best if viewed in fullscreen.

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