1

How could the size of the shadow change, every n seconds? I guess you have to constantly create a new circle and eliminate the previous one? How would this be done? And also, is not there a more optimal way?

function main() {
  var canvas = document.getElementsByTagName("CANVAS")[0],
      ctx = canvas.getContext("2d");
  
  canvas.width = window.innerWidth;
  canvas.height = document.documentElement.scrollHeight;
  var cW = canvas.width,
      cH = canvas.height;
  
  ctx.fillStyle = "#000";
  ctx.fillRect(0, 0, cW, cH);
  ctx.fill();
  
  ctx.beginPath();
  ctx.fillStyle = "#FFF";
  ctx.shadowBlur = 5;
  ctx.shadowColor = "#FFF";
  ctx.arc(cW/2, cH/2, 50, 0, 2 * Math.PI, false);
  ctx.fill();
  ctx.closePath();
}

window.addEventListener("load", main);
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <canvas></canvas>
</body>
</html>
ESCM
  • 269
  • 2
  • 13
  • You need the shadowBlur to be updated too? If so, yes, redraw... Otherwise, use [compositing](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation). – Kaiido Apr 24 '18 at 03:40
  • do you absolutely want this using canvas ? can you use divs with css ? – Taki Apr 25 '18 at 01:03
  • Only canvas, no css – ESCM Apr 25 '18 at 21:29

2 Answers2

2

Create a setInterval & an array of colors. Use Math.random to randomly select any color. Modify the main function to accept colors as two parameters.

function main(bckColor, circleColor) {
  var canvas = document.getElementsByTagName("CANVAS")[0],
    ctx = canvas.getContext("2d");
  if (canvas.height) {
    canvas.height = 0;
  }
  canvas.width = window.innerWidth;
  canvas.height = document.documentElement.scrollHeight;
  var cW = canvas.width,
    cH = canvas.height;
  
  ctx.fillStyle = bckColor || "#000";
  //ctx.fillStyle = "red" ;
  ctx.fillRect(0, 0, cW, cH);
  ctx.fill();

  ctx.beginPath();
  ctx.fillStyle = circleColor || "#FFF";
  ctx.shadowBlur = 5;
  ctx.shadowColor = "#FFF";
  ctx.arc(cW / 2, cH / 2, 50, 0, 2 * Math.PI, false);
  ctx.fill();
  ctx.closePath();
}
var colorArray = ['red', 'green', 'yellow', 'blue', 'pink', 'brown', 'orange']
var changeColor = setInterval(function() {

  let bckColor = colorArray[Math.floor(Math.random() * 7 + 1)];
  let circleColor = colorArray[Math.floor(Math.random() * 7 + 1)];
  main(bckColor, circleColor)

}, 2000)
window.addEventListener("load", main);
<canvas></canvas>
brk
  • 48,835
  • 10
  • 56
  • 78
0

instead of animating the canvas itself with a redraw every x seconds, i would suggest using an overlay , create a circle div, position it over the canvas' circle and animate its shadow using css, you'll have all the controls you want like the shadow's color and distance, animation speed ..etc.

here's a fiddle ( the overlay is better positionned )

function main() {
  var canvas = document.getElementsByTagName("CANVAS")[0],
    ctx = canvas.getContext("2d");

  canvas.width = window.innerWidth;
  canvas.height = document.documentElement.scrollHeight;
  var cW = canvas.width,
    cH = canvas.height;

  ctx.fillStyle = "#000";
  ctx.fillRect(0, 0, cW, cH);
  ctx.fill();

  ctx.beginPath();
  ctx.fillStyle = "#FFF";
  ctx.shadowBlur = 5;
  ctx.shadowColor = "#FFF";
  ctx.arc(cW / 2, cH / 2, 50, 0, 2 * Math.PI, false);
  ctx.fill();
  ctx.closePath();

  // position the overlay over the circle
  overlay.style.top = (cH / 2 - 99) + 'px'
  overlay.style.left = (cW / 2 - 50) + 'px'
}

window.addEventListener("load", main);

main()

const animationDuration = 2;

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

overlay.style.animationDuration = animationDuration + 's';

setInterval(function() {
  overlay.style.color = getRandomColor()
}, animationDuration * 1000)
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

canvas {
  width: 100vw;
  height: 100vh;
  display: block;
}

#overlay {
  border-radius: 50%;
  background: none;
  animation: shadow linear infinite;
  margin: auto;
  transform: translate(0, 50%);
  color: green;
  position: absolute;
  z-index: 99;
  width: 100px;
  height: 93px;
}

@keyframes shadow {
  0% 100% {
    box-shadow: 0 0 0
  }
  50% {
    box-shadow: 0 0 50px 20px
  }
}
<canvas></canvas>
<div id="overlay">

</div>
Taki
  • 17,320
  • 4
  • 26
  • 47
  • oh, no special reason, i think i just forgot it there .. here's a fiddle calling it only once https://jsfiddle.net/3k7sdwvz/1/ – Taki Apr 25 '18 at 21:55