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

Obfuscated Canvas Commands

  1. const oCan = (
  2.   d = document,
  3.   b = d.body,
  4.   canvas = b.appendChild(document.createElement('canvas')),
  5.   c = canvas.getContext('2d'),
  6.   props = [],
  7.   o = {},
  8.   docs = {},
  9.   cmds = [],
  10.   L,
  11.   k,
  12.   du,
  13.   j,
  14.   draw,
  15.   id
  16. ) => {
  17.   ;(onresize = () => {
  18.     canvas.width = innerWidth
  19.     canvas.height = innerHeight
  20.     if (draw) {
  21.       clearTimeout(id)
  22.       id = setTimeout(() => cmds.forEach(v => draw(v)), 500)
  23.     }
  24.   })()
  25.  
  26.   Object.assign(b.style, { margin: 0, height: '100%' })
  27.  
  28.   // longer way: console.log(Object.getOwnPropertyNames(Object.getPrototypeOf(c)));
  29.   for (let i in c) props.push(i)
  30.  
  31.   // make alphabetical since object keys have
  32.   // no order
  33.   props.sort().map(i => {
  34.     L = i.match(/[A-Z]/)
  35.     k = i[0]
  36.     if (L) k += L[0]
  37.     du = 0
  38.     if (o[k]) {
  39.       j = 0
  40.       while (o[k]) k += i[++j]
  41.     }
  42.  
  43.     o[k] =
  44.       (typeof c[i])[0] == 'f'
  45.         ? (...args) => c[i].apply(c, args)
  46.         : v => (c[i] = v)
  47.     docs[i] = k
  48.   })
  49.  
  50.   console.log('docs:', JSON.stringify(docs, null, 2))
  51.  
  52.   return (draw = (s, cmd, currFn, args = [], part, fn, num) => {
  53.     cmd = s.split(/\s+/)
  54.     cmds.push(s)
  55.     c.save()
  56.     for (let i = 0; i < cmd.length; i++) {
  57.       part = cmd[i]
  58.       fn = o[part]
  59.       if (fn && currFn != fn) {
  60.         currFn && currFn.apply(c, args)
  61.         currFn = fn
  62.         args = []
  63.       } else {
  64.         num = parseFloat(part)
  65.         args.push(!isNaN(num) ? num : part)
  66.       }
  67.     }
  68.     currFn && currFn.apply(c, args)
  69.     c.restore()
  70.   })
  71. }
  72.  
  73. const c = oCan()
  74. // `font` & text not suppoted
  75. // make str a function so resize works?
  76. c(`
  77.   fS #ccc
  78.   fR 0 0 400 ${innerHeight}
  79.   fS blue
  80.   fR 40 0 20 20
  81.   gCl difference
  82.   ro .25
  83.   fR 50 0 30 30
  84.   gCl source-over
  85.   fS rgba(200,100,9)
  86.   fR 100 100 40 40
  87.   `)

I’ve had this idea for a long time, never bothered doing it until now. I wrote it in a semi-golfed style for no reason… Anyway, this lets you write canvas code in a strange obfuscated syntax that looks like this:

  1. c(`
  2.   fS #ccc
  3.   fR 0 0 400 ${innerHeight}
  4.   fS blue
  5.   fR 40 0 20 20
  6.   gCl difference
  7.   ro .25
  8.   fR 50 0 30 30
  9.   gCl source-over
  10.   fS rgba(200,100,9)
  11.   fR 100 100 40 40
  12.   `)

This snippet logs out some JSON that shows all the method aliases for the canvas context.

Proxy Quick DOM

  1. const spec = {
  2.   get(o, key) {
  3.     return o[key] != null ? 
  4.       o[key] : o[key] = (...args) => {
  5.         const el = document.createElement(key);
  6.         args.forEach(arg => { 
  7.           if (typeof arg === 'string') {
  8.             const span = document.createElement('span');
  9.             span.innerHTML = arg;
  10.             el.appendChild(span);
  11.           } else if (typeof arg === 'object') {
  12.             if (arg.tagName != null) {
  13.               el.appendChild(arg);
  14.             } else {
  15.               for (let i in arg) {
  16.                 el.setAttribute(i, arg[i]);
  17.               }
  18.             }
  19.           }
  20.         });
  21.         return el;
  22.       }
  23.   },
  24.   set(o, key, v) {
  25.     o[key] = v;
  26.   }
  27. }
  28.  
  29. const dom = new Proxy({}, spec);
  30.  
  31. document.body.appendChild(
  32.   dom.div(
  33.     dom.button('cool'), 
  34.     dom.h2('some text', { style: 'font-style: italic' }), 
  35.     dom.br(), 
  36.     dom.input({ placeholder: 'zevan' })
  37.   )
  38. );
  39.  
  40. const { div, input, label } = dom;
  41. document.body.appendChild(
  42.   div(
  43.     label(
  44.       'Slider:',
  45.       { 
  46.         for: 'slider', 
  47.         style: 'padding:1em;display:block' 
  48.       },
  49.       input({ id: 'slider', type: 'range' })
  50.     )
  51.   )
  52. );

In this snippet a proxy is used that makes all html node tagNames valid methods. Each method can take strings and HTMLElements as arguments in any order to create a dom structure. This may look familiar to people who have looked a bit deeper into the inner workings of some of the popular UI libraries of the last decade.

// dom // hacks // javascript // proxies // tricks // ui

Add Getter Setter to Object

  1. const target = {}
  2.  
  3. let value = null;
  4. Object.defineProperties(target, {
  5.   magic: {
  6.     get() {
  7.       console.log('- getter called::', value);
  8.       return value;
  9.     },
  10.     set(val) {
  11.       document.body.innerHTML += val + '<br>';
  12.       value = val;
  13.     }
  14.   }
  15. });
  16.  
  17. target.magic = 'xyz';
  18. target.magic = 'snippet';
  19. target.magic = 'zone';
  20. target.magic = '- last value';
  21.  
  22. console.log('getting', target.magic);

This snippet shows a way to add getters and setters to a specific key of an existing object. This is powerful for decorating configuration objects with special behaviors. This kind of thing can easily be created with a little more abstraction:

  1. const image = view({
  2.   tag: 'img', 
  3.   src: 'myImage.jpg',
  4.   x: '20%', 
  5.   y: '20%',
  6.   size: '50%'
  7. });
  8. const prev = view({
  9.   tag: 'button',
  10.   x: () => image.x,
  11.   y: () => image.bottom
  12. });
  13. const next = view({
  14.   tag: 'button',
  15.   x: () => image.right - this.width,
  16.   y: () => image.bottom
  17. });

Nonsense Logs

  1. const SPEED = 700;
  2.  
  3. const addKeys = obj => {
  4.   obj.keys = Object.keys(obj)
  5.   return obj
  6. }
  7.  
  8. const wordParts = {
  9.   start: addKeys({
  10.     z: .3,
  11.     zim: .1,
  12.     zz: .1,
  13.     zzz: .1,
  14.     ziz: .05,
  15.     zoo: .1,
  16.     koe: .05,
  17.     kob: .05,
  18.     'cow cow': .1,
  19.     'how ': .02,
  20.     sl: .1,
  21.     ko: .05
  22.   }),
  23.  
  24.   mid: addKeys({
  25.     i: .1,
  26.     oo: .1,
  27.     a: .1,
  28.     e: .3,
  29.     oe: .1,
  30.     ebobe: .1,
  31.     y: .1
  32.   }),
  33.  
  34.   end: addKeys({
  35.     z: .3,
  36.     n: .1,
  37.     t: .05,
  38.     rat: .1,
  39.     '!': .05,
  40.     '?': .05,
  41.     '': .1
  42.   })
  43. };
  44.  
  45. const wordPart = (
  46.     type,
  47.     dupeOdds = .1,
  48.     dupeMax = 8,
  49.     capOdds = .05
  50.   ) => {
  51.  
  52.   let result = '';
  53.   const part = wordParts[type];
  54.   while (result === '') {
  55.     const choice = part.keys[
  56.       Math.floor(Math.random() * part.keys.length)
  57.     ];
  58.     if (Math.random() < part[choice]) {
  59.       result = choice;
  60.       if (Math.random() < dupeOdds) {
  61.         const dupes = Math.round(
  62.           Math.random() * Math.random() * dupeMax
  63.         );
  64.         result = result.repeat(dupes);
  65.       }
  66.     }
  67.   }
  68.   wordPart.accum += result;
  69.  
  70.   if (Math.random() < capOdds) {
  71.     wordPart.accum = wordPart.accum.toUpperCase()
  72.   }
  73.   return wordPart;
  74. }
  75. wordPart.accum  = '';
  76.  
  77. const word = () =>
  78.   wordPart('start')('mid')('end').accum + ' '
  79.  
  80. document.body.style.fontSize="2em";
  81. setInterval(() => {
  82.   document.body.innerHTML += word();
  83.   wordPart.accum = ''
  84. }, SPEED);

Sometimes to entertain myself I will write nonsense style print/log statements. Things like console.log('cowcow'). This snippet generates a variety of these kinds of phrases.

Random Hex Color (semi-golfed)

  1. document.body.innerHTML += 'click anywhere...'
  2.  
  3. onclick = () =>
  4.   document.body.style.background = 
  5.     `#${Math.random().toString(16).substr(-6)}`

I golfed this snippet slightly for no reason in particular. I recently posted a nice readable way to make random hsl colors. This snippet generates a random hexidecimal color.

How it works:

  1. Math.random() // random number between 0 and 1
  2.  
  3. .toString(16) // convert to hex string (something like "0.2d6bcee4198d4")
  4.  
  5. .substr(-6) // grab the last 6 characters

Here is a non-golfed version:

  1. const instructionsEl = document.createElement('p');
  2. instructionsEl.innerHTML = 'click anywhere...';
  3. document.body.appendChild(instructionsEl);
  4.  
  5. const randomHexColor = () => 
  6.   `#${Math.random().toString(16).substr(-6)}`;
  7.  
  8. document.addEventListener('click', () => {
  9.   document.body.style.background = randomHexColor();
  10. });
// codegolf // color // css // golfed // hex // javascript
snippet.zone ~ 2021-24 /// {s/z}