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

crystl

  1. const canvas = document.createElement('canvas')
  2. const c = canvas.getContext('2d')
  3.  
  4. let w;
  5. let h;
  6.  
  7. onresize = e => {
  8.   w = innerWidth * 2
  9.   h = innerHeight * 2
  10.   canvas.width = w
  11.   canvas.height = h
  12.   canvas.style.width = (w / 2) + 'px'
  13.   canvas.style.height = (h / 2) + 'px'  
  14.   c.fillStyle = '#000'
  15.   c.fillRect(0, 0, w, h) 
  16. }
  17. onresize()
  18.  
  19. document.body.append(canvas)
  20. canvas.style.filter = 'contrast(2) brightness(1.2)'
  21.  
  22. class Crystal {
  23.   constructor() {
  24.     this.init()
  25.   }
  26.   init() {
  27.     this.x = w / 2
  28.     this.y = h * .7
  29.     this.rad = 250
  30.  
  31.     this.sides = 5
  32.     // + ~~(Math.random() * 5)
  33.     this.shrinkTime = 400 + Math.random() * 100 
  34.     this.t = Math.random() * 7
  35.     this.st = this.t;
  36.     this.step = (Math.PI * 2) / this.sides
  37.     this.time = 0
  38.     this.shrinkSpeed = 1.3 - Math.random() * .6
  39.     this.a = 0
  40.     this.ad = .05
  41.   }
  42.  
  43.   draw() { 
  44.  
  45.     this.a += (this.ad - this.a) / 150
  46.     c.lineWidth = 5
  47.     c.strokeStyle = `rgba(255, 255, 255, ${this.a})`
  48.     c.fillStyle = `rgba(0, 111, 122, ${this.a / 2})`
  49.     c.beginPath()
  50.  
  51.     for (let j = 0; j < 2; j++) {
  52.       this.time++
  53.       if (this.time > this.shrinkTime) {
  54.         this.rad -= this.shrinkSpeed
  55.         if (this.rad < 0) {
  56.           setTimeout(() => {
  57.             c.fillStyle = 'rgba(0, 0, 0, .02)'
  58.             c.fillRect(0, 0, w, h)
  59.             this.init()
  60.           }, 500)
  61.           return;
  62.         }
  63.       }
  64.       this.t = this.st
  65.       for (let i = 0; i < this.sides; i++) {
  66.         let p = {
  67.           x: this.rad * Math.cos(this.t),
  68.           y: this.rad * .6 * Math.sin(this.t)
  69.         }
  70.         this.t += this.step;
  71.         if (i === 0) {
  72.           c.moveTo(this.x + p.x, this.y + p.y)
  73.         } else {
  74.           c.lineTo(this.x + p.x, this.y + p.y)
  75.         }
  76.       }
  77.       c.closePath()
  78.       c.stroke() 
  79.       c.fill()
  80.  
  81.  
  82.       this.y -= 1
  83.     }
  84.   }
  85. }
  86.  
  87. let cryst = new Crystal()
  88.  
  89.  
  90. setInterval(() => {
  91.   for (let i = 0; i < 3; i++) cryst.draw()
  92. }, 16)

quick crystal for recent youtube short…

Two Circles Explode

  1. const { random, min, sqrt, cos, sin, PI } = Math
  2. let TWO_PI = PI * 2
  3. let minSize
  4.  
  5. document.body.style.margin = 0
  6. document.body.style.background = 'black'
  7. const canvas = document.body.appendChild(
  8.   document.createElement('canvas')
  9. )
  10. const c = canvas.getContext('2d')
  11.  
  12. addEventListener('resize', resize)
  13. resize()
  14.  
  15. function resize() {
  16.   canvas.width = innerWidth
  17.   canvas.height = innerHeight
  18.   minSize = min(innerWidth, innerHeight)
  19.   clear()
  20. }
  21.  
  22. function clear() {
  23.   c.fillStyle = 'rgba(0, 0, 0, .15)'
  24.   c.fillRect(0, 0, innerWidth, innerHeight)
  25. }
  26.  
  27. let dots = []
  28. function dot({x, y, vx, vy, rad, grav = .15}) {
  29.   let sx = x
  30.   let sy = y
  31.   let svx = vx
  32.   let svy = vy
  33.   let intersected
  34.   let partsNum = 20
  35.   let parts = []
  36.   let delay = random() * 5
  37.   let time = 0
  38.  
  39.   dots.push(() => y > innerHeight)
  40.  
  41.   return {
  42.     step() {
  43.       time++
  44.       if (time < delay) return
  45.       if (intersected) {
  46.         for (let i = 0; i < partsNum; i++) {
  47.           parts[i].step()
  48.         }
  49.         return
  50.       }
  51.       x += vx
  52.       y += vy
  53.       vy += grav;
  54.       c.beginPath()
  55.       c.arc(x, y, rad(), 0, 7)
  56.       c.fill()
  57.     },
  58.     reset() {
  59.       x = sx;
  60.       y = sy;
  61.       vx = svx;
  62.       vy = svy;
  63.       intersected = false
  64.     },
  65.     hit() {
  66.       if (!intersected) {
  67.         partsNum = rad() / 3
  68.         for (let i = 0; i < partsNum; i++) {
  69.           let t = random() * TWO_PI
  70.           let r = 5 + random() * 5
  71.           let size = random() * 10
  72.  
  73.           parts.push(
  74.             dot({
  75.               x, y,
  76.               vx: r * cos(t),
  77.               vy: r * sin(t),
  78.               rad: () => size
  79.             })
  80.           )
  81.         }
  82.       }
  83.       intersected = true
  84.     },
  85.     get x() {
  86.       return x
  87.     },
  88.     get y() {
  89.       return y
  90.     }
  91.   }
  92. }
  93.  
  94. const bigRad = () => minSize * .14;
  95.  
  96. let leftDot
  97. let rightDot
  98.  
  99. function start() {
  100.  
  101.   rightDot = dot({
  102.     x: innerWidth, 
  103.     y: innerHeight / 2, 
  104.     vx: -innerWidth * .005, 
  105.     vy: -6, rad: bigRad
  106.   })
  107.  
  108.   leftDot = dot({
  109.     x: 0, 
  110.     y: innerHeight / 2, 
  111.     vx: innerWidth * .005, 
  112.     vy: -6, rad: bigRad
  113.   })
  114. }
  115. start()
  116.  
  117. function collide(a, b) {
  118.   const dx = a.x - b.x
  119.   const dy = a.y - b.y
  120.   const dist = sqrt(dx**2 + dy**2)
  121.   return dist <= bigRad() * 1.8
  122. }
  123.  
  124. function loop() {
  125.   let inc = 2
  126.  
  127.   clear()
  128.   c.fillStyle = 'white'
  129.   if (collide(leftDot, rightDot)) {
  130.  
  131.     leftDot.hit()
  132.     rightDot.hit()
  133.   }
  134.  
  135.   leftDot.step()
  136.   rightDot.step()
  137.  
  138.   dots.forEach(done => {
  139.     if (done()) inc++;
  140.   }) 
  141.  
  142.   if (dots.length > 2 && inc == dots.length)  {
  143.     dots = []
  144.     start()
  145.   }
  146.  
  147.   requestAnimationFrame(loop)
  148. }
  149. loop()

Two circles intersect and explode repeatedly… works at any browser size…

Grads

  1. const grad = {
  2.   gen(c) {
  3.     const canvas = c.canvas;
  4.     const t = Math.random() * 2 * Math.PI;
  5.     const cx = canvas.width / 2;
  6.     const cy = canvas.height / 2;
  7.     const r = Math.max(cx, cy);
  8.     const x1 = cx * Math.cos(t);
  9.     const y1 = cy * Math.sin(t);
  10.     const x2 = cx * Math.cos(t + Math.PI);
  11.     const y2 = cy * Math.sin(t + Math.PI);
  12.  
  13.     const drawFn = c => {
  14.       const g = c.createLinearGradient(x1, y1, x2, y2);
  15.       g.addColorStop(0, 'white');
  16.       g.addColorStop(1, 'black');
  17.  
  18.       c.fillStyle = g;
  19.       c.fillRect(0, 0, canvas.width, canvas.height);
  20.     };
  21.  
  22.     drawFn(c);
  23.   }
  24. };
  25.  
  26. Object.assign(document.body.style, { 
  27.     margin: 0,
  28.     display: 'grid',
  29.     'grid-template-columns': '1fr 1fr 1fr',
  30.   });
  31. const modes = 'screen,overlay,darken,lighten,color-dodge,color-burn,hard-light, soft-light,difference,exclusion,hue,saturation,color,luminosity,multiply'.split(',');
  32.  
  33. for (let j = 0; j < 21; j++) { 
  34.   const SIZE = 200;
  35.   const c = document.body.appendChild(
  36.     document.createElement('canvas')
  37.   ).getContext('2d');
  38.  
  39.   c.canvas.width = c.canvas.height = SIZE;
  40.   Object.assign(c.canvas.style, {
  41.     position: 'relative', 
  42.     width: '100%'
  43.   })
  44.  
  45.  
  46.   c.fillStyle = `hsl(${Math.random() * 20 + 190}deg, 50%, 50%)`
  47.   c.fillRect(0, 0, SIZE, SIZE)
  48.  
  49.   for (let i = 0; i < 5; i++) { 
  50.     c.globalAlpha = .5;
  51.     c.globalCompositeOperation = modes[~~(Math.random() * modes.length)]
  52.     grad.gen(c)
  53.   }
  54. }

Not sure what this is… used the random gradient code and variations on it a few times….

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.

Conic Accident

  1. conicBtn.onclick = () => {
  2.   document.body.innerHTML += `
  3.   <style>
  4.     div {
  5.       background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
  6.     }
  7.   </style>
  8.   `
  9. }

get ready….



When I created the gradient conic snippet from a few days ago – I accidentally applied the rule to the entire page…. thought it was funny enough to be worth making a snippet out of 😀

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