1

I made a fireworks in canvas. I want to duplicate this to a random location inside the canvas.

Finally, I want to run in random order from random locations. What more should I add?

var ctx = document.getElementById('canvas').getContext('2d');

ctx.translate(100, 100);

function fireworks() {
  //clipping
  ctx.beginPath();
  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
  ctx.clip();

  var x = 130; //final position
  var t = 0; //0-1, this is what you change in animation loop
  var tx = 0; //actual position of element for x

  function myLoop() {
    ctx.clearRect(-(canvas.width / 2), -(canvas.height / 2), canvas.width, canvas.height);
    tx = EasingFunctions.easeInOutQuad(t) * x;
    for (var i = 0; i < 12; i++) {
      ctx.beginPath();
      ctx.rotate(Math.PI / 6);
      ctx.arc(tx, tx, 5, 0, Math.PI * 2);
      ctx.fill();
      ctx.closePath();
    }

    if (t < 1) {
      t += 0.01; //determines speed
      requestAnimationFrame(myLoop);
    }
  }
  myLoop();
}
EasingFunctions = {
  easeInOutQuad: function(t) {
    return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t
  }
}


fireworks();
#canvas {
  border: 1px solid #000;
}
<canvas id="canvas" width="800" height="600"></canvas>
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
ssin
  • 13
  • 2

1 Answers1

0

The solution contains some steps:

  1. Call to fireworks once the last "firework" done.
  2. Random the initial firework's position.
  3. Clear the clip state by .restore() and .save()

I've added comments in the code.

var ctx = document.getElementById('canvas').getContext('2d');

function fireworks() {
  // restore and save to reset the "clip" state
  ctx.restore();
  ctx.save();
  //clipping
  ctx.beginPath();
  // move to a random position in the canvas before drawing
  ctx.translate(random(canvas.width), random(canvas.height));
  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
  ctx.clip();

  let tx = 0; //actual position of element for x
  let t = 0;

  function myLoop() {
    ctx.clearRect(-(canvas.width / 2), -(canvas.height / 2), canvas.width, canvas.height);
    tx = EasingFunctions.easeInOutQuad(t) * 130;
    for (var i = 0; i < 12; i++) {
      ctx.beginPath();
      ctx.rotate(Math.PI / 6);
      ctx.arc(tx, tx, 5, 0, Math.PI * 2);
      ctx.fill();
      ctx.closePath();
    }

    if (t < 1) {
      t += 0.01; //determines speed
      requestAnimationFrame(myLoop);
    } else {
      // the firework is done, let's create another one
      fireworks();
    }
  }
  myLoop();
}

function random(max, min = 0) {
  return Math.floor(Math.random() * max) + 1;
}

EasingFunctions = {
  easeInOutQuad: function(t) {
    return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t
  }
}

fireworks();
#canvas {
  border: 1px solid #000;
}
<canvas id="canvas" width="800" height="600"></canvas>
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • You are a genius! Thank you so much for your help! – ssin Jan 21 '20 at 02:45
  • :) Glad I could help. Good luck! – Mosh Feu Jan 21 '20 at 08:29
  • Hi, again. Your comment was very nice. but I have another problem. How can I run the next fireworks before the first one is completely over? I thought about it all day but couldn't find the answer. – ssin Jan 21 '20 at 14:33
  • Indeed it's more complicated. Do you need specifically this effect? Because there is a library that create great fireworks: https://tswaters.github.io/fireworks/, https://github.com/tswaters/fireworks – Mosh Feu Jan 21 '20 at 18:46
  • oh... I didn't know that was a complicated task. ok I will study the link you gave me. have a nice a day! :D – ssin Jan 22 '20 at 02:14
  • Let me know if you manage to complete your task with that library.. – Mosh Feu Jan 22 '20 at 12:29