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

Gray Gradient Texture

  1. function rect(x1, y1, x2, y2, col, blur = 0.1) {
  2.   const dx = x1 - x2;
  3.   const dy = y1 - y2;
  4.   const dist = Math.sqrt(dx * dx + dy * dy);
  5.   return `radial-gradient(circle at ${x1}% ${y1}%, ${col} 0, ${col} ${dist}%, transparent ${dist +
  6.     blur}%)`;
  7. }
  8. const blends = 'multiply,screen,overlay,darken,lighten,color-dodge,color-burn,hard-light,soft-light,difference,exclusion,hue'.split(
  9.   ','
  10. );
  11. const cols = ['black', 'white'];
  12.  
  13. function gen() {
  14.   [...document.querySelectorAll('div')].forEach(d =>
  15.     d.parentNode.removeChild(d)
  16.   );
  17.   for (let j = 0; j < 4; j++) {
  18.     const rects = [];
  19.     for (let i = 0; i < 10; i++) {
  20.       const x = Math.random() * 100;
  21.       const y = Math.random() * 100;
  22.       const s = Math.random() * Math.random() * Math.random() * 30 + 3;
  23.       const col = cols[~~(Math.random() * cols.length)];
  24.       rects.push(rect(x, y, x + s, y + s, col, Math.random() * 10));
  25.     }
  26.     const el = document.body.appendChild(document.createElement('div'));
  27.     el.style.backgroundImage = rects.join(', ');
  28.     el.style.mixBlendMode = blends[~~(Math.random() * blends.length)];
  29.   }
  30. }
  31. gen();
  32.  
  33. document.body.innerHTML += `
  34.   <button id="regen">Regenerate</button>
  35.   <style>
  36.     body, html {
  37.       height: 100%;
  38.       background: #ccc;
  39.       margin: 0;
  40.       background-repeat: no-repeat;
  41.       width: 100%;
  42.     }
  43.     div {
  44.       position: absolute;
  45.       top: 0; left: 0;
  46.       width: 100%;
  47.       height: 100%;
  48.     }
  49.     #regen {
  50.       position: absolute;
  51.       width: 100px;
  52.       height: 30px;
  53.       background: #ccc;
  54.       border: 1px solid white;
  55.       margin: 1em;
  56.       cursor: pointer;
  57.       transition: all 250ms ease-out;
  58.       z-index: 999;
  59.     }
  60.     #regen:hover { background: #333; color: white; }
  61.   </style>
  62. `;
  63.  
  64. regen.onclick = gen;

Playing around some more with lots of linear gradients.

Interesting Color Picker

  1. document.addEventListener('touchmove', e => e.preventDefault(), {
  2.   passive: false
  3. });
  4.  
  5. document.body.innerHTML += `
  6. <style>
  7.   * {
  8.     -moz-user-select: none;
  9.     -webkit-user-select: none;
  10.     -ms-user-select: none;
  11.     user-select: none;
  12.   }
  13.   body {
  14.     background: #333;
  15.   }
  16.   .select-box {
  17.     border: 1px solid white;
  18.     outline: 1px solid black;
  19.   }
  20.   .swatch {
  21.     border: none;
  22.     outline: none;
  23.   }
  24. </style>
  25. `;
  26.  
  27. const col = document.body.appendChild(document.createElement('div'));
  28. Object.assign(col.style, {
  29.   position: 'absolute',
  30.   left: 0,
  31.   top: 0,
  32.   width: '100%',
  33.   height: '200px',
  34.   background:
  35.     `linear-gradient(0, black 0%, transparent 50%, transparent 50%, white 100%), 
  36.      linear-gradient(90deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000)`
  37. });
  38.  
  39. const swatches = document.body.appendChild(document.createElement('div'));
  40. Object.assign(swatches.style, {
  41.   position: 'absolute',
  42.   top: '200px',
  43.   left: 0,
  44.   width: '100%'
  45. });
  46.  
  47. function box(x, y, cls = 'select-box', parent = document.body) {
  48.   const box = parent.appendChild(document.createElement`div`);
  49.   box.classList.add(cls);
  50.   Object.assign(box.style, {
  51.     position: 'absolute',
  52.     left: `${x}%`,
  53.     top: `${y}px`,
  54.     width: '40px',
  55.     height: '40px',
  56.     background: 'none',
  57.     transform: 'translate(-50%, -50%)',
  58.     cursor: 'pointer',
  59.  
  60.     color: 'white'
  61.   });
  62.   return box;
  63. }
  64.  
  65. function touch(e) {
  66.   let x = e.clientX;
  67.   let y = e.clientY;
  68.   if (e.touches != null && e.touches.length > 0) {
  69.     x = e.touches[0].clientX;
  70.     y = e.touches[0].clientY;
  71.   }
  72.   return { x, y };
  73. }
  74.  
  75. document.addEventListener('touchstart', onDown);
  76. document.addEventListener('touchmove', onMove);
  77. document.addEventListener('touchend', onUp);
  78. document.addEventListener('mousedown', onDown);
  79. document.addEventListener('mousemove', onMove);
  80. document.addEventListener('mouseup', onUp);
  81.  
  82. let down = false;
  83. let currBox;
  84. let currSwatch;
  85. let swatchHeight = 30;
  86. let id = 0;
  87.  
  88. function toHSL(x, y) {
  89.   let deg = x * 360;
  90.   return `hsl(${deg}deg, 100%, ${100 - y / 2}%)`;
  91. }
  92.  
  93. function onDown(e) {
  94.   let { x, y } = touch(e);
  95.   down = true;
  96.   let hPercent = x / innerWidth;
  97.   let color = toHSL(hPercent, y);
  98.   if (e.target.classList.contains('swatch')) {
  99.     e.target.style.outline = '2px solid red';
  100.     e.target.style.zIndex = 999;
  101.     down = false;
  102.     setTimeout(() => {
  103.       if (confirm('Would you like to remove this swatch?')) {
  104.         currBox = document.querySelector(
  105.           `.select-box[data-id="${e.target.dataset.id}"]`
  106.         );
  107.  
  108.         if (currBox != null) {
  109.           currBox.parentNode.removeChild(currBox);
  110.           e.target.parentNode.removeChild(e.target);
  111.         }
  112.       } else {
  113.         e.target.style.outline = null;
  114.         e.target.style.zIndex = null;
  115.       }
  116.     }, 250);
  117.   } else if (e.target.classList.contains('select-box')) {
  118.     currBox = e.target;
  119.     c = document.querySelector(`.swatch[data-id="${currBox.dataset.id}"]`);
  120.   } else {
  121.     currBox = box(hPercent * 100, y);
  122.     currBox.dataset.id = id++;
  123.     currSwatch = box(0, 0, 'swatch', swatches);
  124.     currSwatch.dataset.id = currBox.dataset.id;
  125.     Object.assign(currSwatch.style, {
  126.       width: '100%',
  127.       position: 'relative',
  128.       height: `${swatchHeight}px`,
  129.       transform: 'none',
  130.       background: color
  131.     });
  132.   }
  133. }
  134.  
  135. function onMove(e) {
  136.   if (down) {
  137.     let { x, y } = touch(e);
  138.     let hPercent = x / innerWidth;
  139.     let color = toHSL(hPercent, y);
  140.     Object.assign(currBox.style, {
  141.       left: `${hPercent * 100}%`,
  142.       top: `${y}px`
  143.     });
  144.     currSwatch.style.background = color;
  145.   }
  146. }
  147.  
  148. function onUp(e) {
  149.   down = false;
  150.   currBox = null;
  151. }

Click anywhere on the spectrum to add a color… color boxes can be dragged, color swatches can be deleted by clicking on them…

Just something that popped into my head awhile back so figured I’d do a speed-coded prototype. I’d like to revisit this and add more to it.

Oscillating Canvas Wave

  1. const c = document.body
  2.   .appendChild(document.createElement('canvas'))
  3.   .getContext('2d');
  4.  
  5. Object.assign(document.body.style, {
  6.   margin: 0,
  7.   height: '100%'
  8. });
  9.  
  10. Object.assign(c.canvas.style, {
  11.   position: 'absolute',
  12.   left: 0,
  13.   top: 0,
  14.   width: '100%',
  15.   height: '100%'
  16. });
  17.  
  18. let t = 0;
  19.  
  20. function resize() {
  21.   c.canvas.width = innerWidth * 2;
  22.   c.canvas.height = innerHeight * 2;
  23.   draw();
  24. }
  25. window.addEventListener('resize', resize);
  26. resize();
  27.  
  28. function draw() {
  29.   const {
  30.     canvas: { width, height }
  31.   } = c;
  32.  
  33.   c.fillStyle = 'rgba(155, 155, 155, .4)';
  34.   c.fillRect(0, 0, width, height);
  35.   c.fillStyle = '#000';
  36.  
  37.   let x = innerWidth;
  38.   let y = 0;
  39.  
  40.   t += 0.05;
  41.   for (let i = 0; i < innerHeight; i++) {
  42.     x += 2 * Math.cos(t + i * 0.1 * Math.cos(i / 200));
  43.     y += 2;
  44.     c.fillRect(x, y, 100, 1);
  45.   }
  46. }
  47.  
  48. function loop() {
  49.   draw();
  50.   window.requestAnimationFrame(loop);
  51. }
  52. loop();

Speed coded oscillating wave on canvas… Looks better in fullscreen.

Tab Timer

  1. <title id=t></title>
  2. <script>
  3.   st = Date.now()
  4.   setInterval(_ => {
  5.     s = Date.now() - st
  6.     t.innerHTML = 
  7.       ~~(s/6e4)+':'+(~~(s/1e3)%60)
  8.   }, 500)
  9. </script>

I speed coded this recently to put a timer in a brower tab.

Have a look at it here in a new tab…

Obviously this is pretty odd – but it does work for my purposes 😉

Gravity Dots 2

  1. d = document
  2. b = d.body
  3. b.style.margin = 0
  4. b.style.background = 'black'
  5. r = (v = 1) => Math.random() * v
  6.  
  7. with(
  8.   b.appendChild(
  9.     d.createElement`canvas`
  10.   ).getContext`2d`) {
  11.  
  12.   onresize = () => {
  13.     canvas.width = innerWidth
  14.     canvas.height = innerHeight
  15.   }
  16.   onresize()
  17.  
  18.   fillStyle = 'red'
  19.  
  20.   dot = (
  21.     x = r(innerWidth),
  22.     y = 0,
  23.     mass = 20, sr = r(2) + 2, 
  24.     R = sr,
  25.     dx, dy,
  26.     col = '#005eb0',
  27.     dist, vx = .2, vy = 0) => { 
  28.  
  29.     return () => { 
  30.       fillStyle = col
  31.       R = sr
  32.       if (r() < .001) {
  33.         vx = r() * 4 - 2
  34.         R = sr * 2
  35.         fillStyle = 'red'
  36.         col = `hsl(${r(360)}deg, 50%, 50%)`
  37.       }
  38.  
  39.       dx = innerWidth / 2 - x
  40.       dy = innerHeight / 2 - y
  41.       dist = Math.sqrt(dx * dx + dy * dy)
  42.       dist *= dist
  43.       vx += dx / dist * mass
  44.       vy += dy / dist * mass
  45.  
  46.       x += vx
  47.       y += vy
  48.  
  49.       beginPath()
  50.       arc(x, y, R, 0, 6.29)
  51.       fill()
  52.     }
  53.   }
  54.  
  55.   const dots = []
  56.   for (let i = 0; i < 100; i++) dots.push(dot())
  57.   loop = () => {
  58.     fillStyle = 'rgba(0, 0, 0, 0.05)'
  59.     fillRect(0, 0, canvas.width, canvas.height)
  60.     dots.map(d => d())
  61.   }
  62.   setInterval(loop, 16)
  63. }

A variation on this recent post.

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