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

Decompose Matrix

1. `const deltaTransformPoint = (matrix, point) => {`
2. `  return {`
3. `    x: point.x * matrix.a + point.y * matrix.c,`
4. `    y: point.x * matrix.b + point.y * matrix.d`
5. `  }`
6. `}`
7. ` `
8. `const decomposeMatrix = matrix => {`
9. `  let px = deltaTransformPoint(matrix, { x: 0, y: 1 })`
10. `  let py = deltaTransformPoint(matrix, { x: 1, y: 0 })`
11. `  let skewX = FROM_RADS * Math.atan2(px.y, px.x) - 90`
12. `  let skewY = FROM_RADS * Math.atan2(py.y, py.x)`
13. ` `
14. `  return {`
15. `    tx: matrix.e,`
16. `    ty: matrix.f,`
17. `    scaleX: Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b),`
18. `    scaleY: Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d),`
19. `    skewX: skewX,`
20. `    skewY: skewY,`
21. `    rotation: skewX`
22. `  }`
23. `}`

Get the scale, translation, rotationa and skew values from a matrix.

Great stackoverflow answer from user dave

// graphics // math // matrix

Random Color Strings Not-Golfed

1. `const { random, round } = Math`
2. ` `
3. `const TICK = 100`
4. `const CHUNKS_PER_TICK = 4`
5. `const minChunk = 3`
6. `const maxChunk = 10`
7. `const diffChunk = maxChunk - minChunk`
8. ` `
9. `const generateChance = .9 // 90% change of string generation`
10. `const spaceChance = .8 // 80% chance of space`
11. `const breakChance = .1 // 10% chance of line break`
12. `const numbersChance = .9`
13. ` `
14. `const randomChunk = () => round(random() * 0xff).toString(36)`
15. `  .replace(random() < numbersChance ? /[0-9]/g : '', '')`
16. ` `
17. `setInterval(() => {`
18. ` `
19. `  if (random() < generateChance) {`
20. ` `
21. `    Array(CHUNKS_PER_TICK).fill(0).forEach(() => { `
22. ` `
23. `      const stringLeng = round(minChunk + random() * diffChunk)`
24. `      let chunk = ''`
25. ` `
26. `      Array(stringLeng).fill(0)`
27. `        .forEach(() => chunk += randomChunk())`
28. ` `
29. `      const span = document.createElement('span')`
30. `      const hue = round(random() * 360)`
31. ` `
32. `      span.style.color = `hsl(\${hue}, 30%, 50%)``
33. `      document.body.appendChild(span)`
34. `      span.innerText = chunk`
35. ` `
36. `      if (random() < spaceChance) { `
37. `        document.body.appendChild(document.createTextNode(' '))`
38. `      }`
39. ` `
40. `      if (random() < breakChance) {`
41. `        const br = document.createElement('br')`
42. `        document.body.appendChild(br)`
43. `      }`
44. ` `
45. `    })`
46. `  }`
47. ` `
48. `  scrollTo(0, document.body.scrollHeight)`
49. `}, TICK)`
50. ` `
51. ` `
52. `// just a lazy hack since snippet zone quick editor only supports js...`
53. `// normally this goes in a separate file... :D`
54. `document.body.innerHTML += ``
55. `<style>`
56. `body, html {`
57. `  background: black;`
58. `  font-family: Oswald, sans-serif;`
59. `  overflow-wrap: break-word;`
60. `  text-transform: uppercase;`
61. `  letter-spacing: 1;`
62. `}`
63. ` `
64. `br {`
65. `  height: 1em;`
66. `  display: block;`
67. `}`
68. `</style>`
69. ```

An expansion on a snippet from a few days ago inspired by a friends codepen fork…

ES5 Canvas Thing

1. `var canvas = document.body.appendChild(`
2. `  document.createElement('canvas')`
3. `),`
4. `c = canvas.getContext("2d"),`
5. `size = canvas.width,`
6. `quarterSize = size / 4,`
7. `eightSize = size / 8,`
8. `halfSize = size / 2,`
9. `TWO_PI = Math.PI * 2,`
10. `bombNum = 3,`
11. `bombs = [],`
12. `wanderers = {}, `
13. `wandererIndex = 0,`
14. `particles = {},`
15. `particleIndex = 0;`
16. ` `
17. `canvas.width = canvas.height = 300`
18. ` `
19. `c.fillStyle = "rgb(100,100,100)";`
20. `c.fillRect(0,0,size,size);`
21. ` `
22. `function Particle(x, y){`
23. `  this.x = x;`
24. `  this.y = y;`
25. `  var rad = 3 + Math.random() * 6;`
26. `  var theta = Math.random() * TWO_PI;`
27. `  this.vx = rad * Math.cos(theta);`
28. `  this.vy = rad * Math.sin(theta);`
29. `  this.alpha = 1;`
30. `  particleIndex++;`
31. `  this.index = particleIndex;`
32. `  particles[this.index] = this;`
33. `}`
34. `Particle.prototype.draw = function(){`
35. `  this.x += this.vx;`
36. `  this.y += this.vy;`
37. `  this.vx *= 0.9;`
38. `  this.vy *= 0.9;`
39. `  this.alpha -= 0.05;`
40. ` `
41. `  if (this.alpha <= 0){`
42. `    this.alpha = 0;`
43. `    delete particles[this.index];`
44. ` `
45. `  }`
46. ` `
47. `  c.fillStyle = "rgba(255,255,255,"+this.alpha+")";`
48. `  c.beginPath();`
49. `  c.arc(this.x, this.y, 1, 0, TWO_PI, false);`
50. `  c.fill();`
51. `};`
52. ` `
53. `function Bomb(){`
54. `  this.x = quarterSize + Math.random() * halfSize;`
55. `  this.y = quarterSize + Math.random() * halfSize;`
56. `  this.radius = 15 + Math.random() * 20;`
57. `}`
58. `Bomb.prototype.draw = function(){`
59. `  c.fillStyle = "#e64c25";`
60. `  c.beginPath();`
61. `  c.arc(this.x, this.y, this.radius, 0, TWO_PI, false);`
62. `  c.fill();`
63. `};`
64. ` `
65. `function Wanderer(x, y){`
66. `  this.x = x;`
67. `  this.y = y;`
68. `  this.vx = Math.random() * 4 - 2;`
69. `  this.vy = Math.random() * 4 - 2;`
70. `  particleIndex++;`
71. `  this.index = particleIndex;`
72. `  particles[this.index] = this;`
73. `}`
74. `Wanderer.prototype.die = function(){`
75. `  for (var j = 0; j < 4; j++){`
76. `    new Particle(this.x, this.y);`
77. `  }`
78. ` `
79. `  delete particles[this.index];`
80. `};`
81. `Wanderer.prototype.draw = function(){`
82. `  this.x += this.vx;`
83. `  this.y += this.vy;`
84. ` `
85. `  if (Math.random() < 0.1){`
86. `    this.vx = Math.random() * 4 - 2;`
87. `    this.vy = Math.random() * 4 - 2;`
88. `  }`
89. ` `
90. `  if (this.x < 0) this.x = size;`
91. `  if (this.x > size) this.x = 0;`
92. `  if (this.y < 0) this.y = size;`
93. `  if (this.y > size) this.y = 0;`
94. ` `
95. `  c.fillStyle = "white";`
96. `  c.beginPath();`
97. `  c.arc(this.x, this.y, 2, 0, TWO_PI, false);`
98. `  c.closePath();`
99. `  c.fill();`
100. ` `
101. `  for (var i = 0; i < bombNum; i++){`
102. `    var bomb = bombs[i];`
103. `    var dx = this.x - bomb.x;`
104. `    var dy = this.y - bomb.y;`
105. `    if (Math.sqrt(dx * dx + dy * dy) < bomb.radius){`
106. `      this.die();`
107. `    }`
108. `  }`
109. `};`
110. ` `
111. `for (var i = 0; i < bombNum; i++){`
112. `  bombs[i] = new Bomb();`
113. `}`
114. ` `
115. `new Wanderer(eightSize, eightSize); `
116. ` `
117. `setInterval(function(){`
118. `  c.fillStyle = "rgba(100,100,100, 0.2)";`
119. `  c.fillRect(0,0,size,size);`
120. `  c.strokeStyle = "white";`
121. `  c.beginPath();`
122. `  c.arc(eightSize, eightSize, 5, 0, TWO_PI, false);`
123. `  c.stroke();`
124. ` `
125. `  if (Math.random() < 0.02){`
126. `    new Wanderer(eightSize, eightSize); `
127. `  }`
128. ` `
129. `  for (var i = 0; i < bombNum; i++){`
130. `    bombs[i].draw();`
131. `  }`
132. ` `
133. `  for (var i in wanderers){`
134. `    wanderers[i].draw(); `
135. `  }`
136. ` `
137. `  for (var i in particles){`
138. `    particles[i].draw();`
139. `  }`
140. `}, 16);`

An old es5 speedcoded thing…

Cut Hole in Canvas (eraser)

1. `document.body.style.background = 'gray';`
2. `const canvas = document.createElement('canvas');`
3. `const c = canvas.getContext('2d');`
4. ` `
5. `canvas.width = 300;`
6. `canvas.height = 300;`
7. ` `
8. `c.fillStyle='rgba(255, 0, 0, 0.8)'`
9. `c.fillRect(0, 0, canvas.width, canvas.height);`
10. ` `
11. `c.globalCompositeOperation = 'destination-out';`
12. `c.fillStyle = 'black';`
13. `c.fillRect(100, 100, 150, 50);`
14. ` `
15. `document.body.appendChild(canvas);`

`destination-out` is great for creating masks and eraser tools – things like that – in this case a 150×50 rectangle is cut out of a red background.

1. `// "Being clever is not clever"`
2. `// -- Bjarne Stroustrup`
3. `D = document`
4. `ang = {`
5. `  '|': 180,`
6. `  '-': 90,`
7. `  '\\': 135,`
8. `  '/': 225`
9. `}`
10. ` `
11. `box = def => {`
12. `  def = def.split(/\s+/)`
13. `  form = def.length`
14. `  I = i => parseInt(def[i], 16)`
15. ` `
16. `  ;[,,, _=>{x = y = I(0); w = h = I(1); c = def[2]},`
17. `    _=>{x = I(0), y = I(1); w = h = I(2);c = def[3]},`
18. `    _=>{x = I(0); y = I(1); w = I(2); h = I(3); c = def[4]}`
19. `  ][form]()`
20. ` `
21. `  c = c.split```
22. ` `
23. `  ca = c[0]`
24. `  ca = ca+ca+ca`
25. `  cD = ang[c[1]]`
26. `  cb = c[2]`
27. `  cb = cb+cb+cb `
28. ` `
29. `  D.body.appendChild(`
30. `    D.createElement`div``
31. `  ).style = ``
32. `    position: absolute; left: \${x}px; top: \${y}px;`
33. `    width: \${w}px; height: \${h}px;`
34. `    background: linear-gradient(\${cD}deg, #\${ca}, #\${cb})`
35. `  ``
36. `}`
37. ` `
38. `const parse = prog => prog.trim()`
39. `  .split(/\n+/m)`
40. `  .map(line => box(line.trim()))`
41. ` `
42. `parse(``
43. `  0 64 0/f`
44. `  64 64 0\\f`
45. `  a0 f0 30 54 f\\0`
46. `  0 6f 20 60 0-c`
47. `  f 7f 20 60 0|c`
48. `  1f 8f 30 30 c/0`
49. ``)`

Just playing around… odd micro-gradient notation:

1. `'0 64 0/f'`
2. `// x=0 y=0 width=0x64 height=0x64`
3. `// 0/f = gradient black to white top right to bottom left`
4. ` `
5. `'64 64 0\\f'`
6. `// x=0 y=0 width=0x64 height=0x64`
7. `// 0\\f = black to to white gradient top left to bottom right`
8. ` `
9. `'0 6f 20 60 0-c'`
10. `// x=0 y=0x6f width=0x20 height=0x60`
11. `// 0-c = gradient black to grey (#ccc) left to right`
12. ` `
13. `// etc... ( | ) is top to bottom grad`
// css // dom // golfed // graphics // hacks // humor // regex // speed-coded
snippet.zone ~ 2021-23 /// {s/z}