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

Save Large Canvas

  1. // https://stackoverflow.com/questions/38781968/problems-downloading-big-filemax-15-mb-on-google-chrome
  2. function dataUriToBlob(dataURI) {
  3.   const binStr = atob(dataURI.split(',')[1]);
  4.   const len = binStr.length;
  5.   const arr = new Uint8Array(len);
  6.   const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
  7.   for (let i = 0; i < len; i++) {
  8.     arr[i] = binStr.charCodeAt(i);
  9.   }
  10.  
  11.   const blob = new Blob([arr], {
  12.     type: mimeString
  13.   });
  14.  
  15.   return URL.createObjectURL(blob);
  16. }
  17.  
  18. const save = document.createElement('a');
  19. save.innerText = 'save this big image';
  20. document.body.appendChild(save);
  21.  
  22. const canvas = document.createElement('canvas');
  23. const c = canvas.getContext('2d');
  24.  
  25. canvas.width = window.innerWidth * 4;
  26. canvas.height = window.innerHeight * 4;
  27. canvas.style.transformOrigin = '0 0';
  28. canvas.style.transform = `scale(0.14)`;
  29. document.body.appendChild(canvas);
  30.  
  31. c.fillStyle = 'black';
  32. c.fillRect(0, 0, canvas.width, canvas.height);
  33.  
  34. const size = Math.max(window.innerWidth, window.innerHeight);
  35.  
  36. // draw some rectangles
  37. c.globalCompositeOperation = 'difference'
  38. for (let i = 0; i < 100; i++) {
  39.   const angle = Math.random() * 180 + 180;
  40.   const color = `hsl(${angle}deg, 50%, 50%)`;
  41.   c.fillStyle = color;
  42.   const width = Math.random() * size + 100;
  43.   const height = Math.random() * size + 100;
  44.   const x = Math.random() * canvas.width - width / 2;
  45.   const y = Math.random() * canvas.height - height / 2;
  46.   c.fillRect(
  47.     x, 
  48.     y, 
  49.     width, 
  50.     height);
  51. }
  52.  
  53. save.download = 'big-image';
  54. save.href = dataUriToBlob(canvas.toDataURL());

Weirdly if you try to save a massive data URI to a file (> 15mb) it will just fail. In order to do this properly, you need to convert to a blob first and then save. I encountered this at some point and learned of the solution from user doppelgreener over at stack overflow. Take a look at the post here.

Wobbling Ball With Canvas

  1. // same as yesterday but with canvas instead of svg
  2. const canvas = document.createElement('canvas'),
  3.       c = canvas.getContext('2d');
  4. document.body.appendChild(canvas);
  5. document.body.style.margin = 0;
  6.  
  7. let w = window.innerWidth,
  8.     h = window.innerHeight,
  9.     x = w / 2,
  10.     y = h / 2,
  11.     vx = vy = dx = dy = 0,
  12.     damp = 0.99, div = 8, ticks = 0, 
  13.     wobbleChance = 0.03,
  14.     startTick = 50;
  15.  
  16. function loop() {
  17.  
  18.   w = window.innerWidth;
  19.   h = window.innerHeight;
  20.   radius = w * 0.05;
  21.   diam = radius * 2;
  22.   diam2x = diam * 2;
  23.  
  24.   if (x > w){
  25.     vx *= -1;
  26.     dx *= -1;
  27.     x = w;
  28.   } else if (x < 0){
  29.     vx *= -1;
  30.     dx *= -1;
  31.     x = 0;
  32.   }
  33.  
  34.   if (y > h) {
  35.     vy *= -1;
  36.     dy *= -1;
  37.     y = h;
  38.   } else if (y < 0) {
  39.     vy *= -1;
  40.     dy *= -1;
  41.     y = 0
  42.   } 
  43.  
  44.   if (
  45.     Math.random() < wobbleChance || 
  46.     ticks === startTick) {
  47.       dx += Math.random() * 10 - 5;
  48.       dy += Math.random() * 10 - 5;
  49.   }
  50.  
  51.   dx *= damp;
  52.   dy *= damp;
  53.  
  54.   vx += (dx - vx) / div;
  55.   vy += (dy - vy) / div;
  56.  
  57.   x += vx;
  58.   y += vy;
  59.  
  60.   // in most cases these days you
  61.   // just clear the whole canvas, but for
  62.   // this example we clear a rectangle around 
  63.   // the circle 
  64.   c.clearRect(
  65.     x - diam, 
  66.     y - diam, 
  67.     diam2x, 
  68.     diam2x
  69.   );
  70.  
  71.   // draw the path
  72.   c.fillStyle = 'red'
  73.   c.beginPath();
  74.   c.arc(x, y, radius, 0, Math.PI * 2, false);
  75.   c.fill();
  76.  
  77.   ticks++;
  78.   window.requestAnimationFrame(loop);
  79. }
  80. loop();
  81.  
  82. function resize() {
  83.   canvas.width = window.innerWidth;
  84.   canvas.height = window.innerHeight;
  85. }
  86. resize();
  87. window.addEventListener('resize', resize);

A wobbling ball with canvas.

Draw a Spiral with Resize

  1. const canvas = document.body.appendChild(
  2.   document.createElement('canvas')
  3. );
  4. const c = canvas.getContext('2d');
  5.  
  6. function resize() {
  7.   canvas.width = window.innerWidth;
  8.   canvas.height = window.innerHeight;
  9.   draw();
  10. }
  11.  
  12. function draw() {
  13.   c.clearRect(0, 0, canvas.width, canvas.height);
  14.   c.fillStyle = 'blue';
  15.  
  16.   const iter = 300,
  17.         halfWidth = window.innerWidth / 2,
  18.         halfHeight = window.innerHeight / 2;
  19.   let rad = 0, theta = 0, x, y;
  20.   for (let i = 0; i < iter; i++) {
  21.     x = halfWidth + rad * Math.cos(theta);
  22.     y = halfHeight + rad * Math.sin(theta);
  23.     c.fillRect(x, y, 5, 5);
  24.     rad += Math.min(window.innerWidth, window.innerHeight) * 0.0015;
  25.     theta += .1;
  26.   }
  27. }
  28.  
  29. resize();
  30. window.addEventListener('resize', resize);

Expanding on yesterdays post, this draws a resizable sprial on a canvas.

Easy Canvas Resize

  1. const canvas = document.body.appendChild(
  2.   document.createElement('canvas')
  3. );
  4. const c = canvas.getContext('2d');
  5.  
  6. function resize() {
  7.   canvas.width = window.innerWidth;
  8.   canvas.height = window.innerHeight;
  9.   draw();
  10. }
  11.  
  12. function draw() {
  13.   c.clearRect(0, 0, canvas.width, canvas.height);
  14.   c.fillStyle = 'red';
  15.   // 30% width and height
  16.   c.fillRect(30, 30, 
  17.     window.innerWidth * .3, 
  18.     window.innerHeight * .3);
  19. }
  20.  
  21. resize();
  22. window.addEventListener('resize', resize);

Resizing a canvas is unusual, because setting the width/height of a canvas completely erases it.

If your canvas isn’t animating, you can just redraw after resizing. Depending on what you’re drawing, working in percentages instead of pixel values can make things easier.

If you hit the “Try it out…” button, go into fullscreen and resize your browser window you’ll see things in action.

Semi-golfed Canvas Setup

  1. ((
  2.   width = 200, height = 200, 
  3.   cnv = document.body.appendChild(
  4.     Object.assign(
  5.       document.createElement('canvas'), {
  6.       width, height
  7.     })
  8.   ),
  9.   c = cnv.getContext('2d'), 
  10.   f = c.fillRect.bind(c),
  11.   C = _ => c.fillStyle = _) => {
  12.  
  13.   C`gray`; f(0, 0, width, height);
  14.   C`blue`; f(10, 10, 100, 20);
  15. })();
snippet.zone /// {s/z}