carretero_1
carretero_1

Reputation: 27

How to make an user create a circle when clicking the canvas

I am new to programming, and to the canvas element. I want to create a blackhole simulation (using basic physics concepts) and I was wondering how can I add interactivity to it.Here is my code:

window.onload = function () {
    var canvas = document.getElementById("space"),
    ctx = canvas.getContext('2d'),
    G = 6.67e-11, //gravitational constant 
    c = 3e8, //speed of light (m/s)
    M = 12e31, // masseof the blackhole in kg (60 solar masses)  
    Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
    pixel_Rs = Rs / 1e3,
    xb = canvas.width / 2, // x coordinate of the blackhole
    yb = canvas.height / 2,// y coordinate of the blackhole
    x = 400,
    y = yb,
    R = 6e3,
     // every pixel variable is a scaled distance           
    distance = (xb - x) * 1e4,
    pixel_distance = distance / 1e3,
    pixel_R = R / 1e3,
    vorbital = Math.sqrt((G * M) / distance),
    perimeter = 2 * Math.PI * distance,
    tcircle = perimeter / vorbital,
    dmsec = 1 / (tcircle / 10e-3),
    dradian = dmsec * 2 * Math.PI;

    setInterval(function () {

        ctx.fillStyle = "#032240";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = "black";
        ctx.beginPath();
        ctx.arc(xb, yb, pixel_Rs, 0, 2 * Math.PI, false);
        ctx.closePath();
        ctx.fill();
        ctx.fillStyle = "grey";
        ctx.beginPath();
        ctx.arc(x, y, pixel_R, 0, 2 * Math.PI, false);
        ctx.closePath();
        ctx.fill();

        ctx.save();
        ctx.translate(xb, yb);
        ctx.rotate(-dradian);
        ctx.translate(-xb, -yb);
    }, 20)
};
<canvas id="space" width="1400" height="850"></canvas>

Now what I want to do is to make the circle that rotates appear and rotate when the user clicks on the canvas, so the coordinates of the mouse click are the ones given by the user, instead of giving it arbitrary coordinates. if you could help me, it'd be great. if you could also tell me how to make the circle disappear if the user clicks on the circle that represent the blackhole would be awesome. Thanks a lot

Ps: Nevermind the calculations.

Upvotes: 1

Views: 93

Answers (1)

alexdmejias
alexdmejias

Reputation: 1419

You can attach an event listener to the canvas like so

    var canvas = document.getElementById('canvas');

    var mousePos;

    canvas.addEventListener('mousedown', function(event) {
        mousePos = {
            x: event.clientX,
            y: event.clientY
        }
    })

In this case mousePos will be an object with the x and y coordinates. To accomplish that you need you would need something like this

    var canvas = document.getElementById("space"),
    ctx = canvas.getContext('2d'),
    G = 6.67e-11, //gravitational constant 
    c = 3e8, //speed of light (m/s)
    M = 12e31, // masseof the blackhole in kg (60 solar masses)  
    Rs = (2 * G * M) / 9e16, //Schwarzchild radius 
    pixel_Rs = Rs / 1e3,
    xb = canvas.width / 2, // x coordinate of the blackhole
    yb = canvas.height / 2,// y coordinate of the blackhole
    x = 400,
    y = yb,
    R = 6e3,
     // every pixel variable is a scaled distance           
    distance = (xb - x) * 1e4,
    pixel_distance = distance / 1e3,
    pixel_R = R / 1e3,
    vorbital = Math.sqrt((G * M) / distance),
    perimeter = 2 * Math.PI * distance,
    tcircle = perimeter / vorbital,
    dmsec = 1 / (tcircle / 10e-3),
    dradian = dmsec * 2 * Math.PI;

    var orbitals = [];

    function Orbital(x, y) {
      this.x = x;
      this.y = y;
    }

    Orbital.prototype.setup = function() {

    };

    Orbital.prototype.draw = function() {
      var mousePos = {
        x: this.x,
        y: this.y
      }

      ctx.fillStyle = "grey";
      ctx.beginPath();
      ctx.arc(mousePos.x, mousePos.y, pixel_R, 0, 2 * Math.PI, false);
      ctx.closePath();
      ctx.fill();
    };

    function draw() {

      ctx.fillStyle = "#032240";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillStyle = "black";
      ctx.beginPath();
      ctx.arc(xb, yb, pixel_Rs, 0, 2 * Math.PI, false);
      ctx.closePath();
      ctx.fill();

      orbitals.forEach(function(orbital) {
        orbital.draw();
      });

      ctx.save();
      ctx.translate(xb, yb);
      ctx.rotate(-dradian);
      ctx.translate(-xb, -yb);

      window.requestAnimationFrame(draw);
    }


    canvas.addEventListener('mousedown', function(event) {
      orbitals.push(new Orbital(event.clientX, event.clientY));
    });



    (function() {
      window.requestAnimationFrame(draw);
    }());

A few things to note. I created a new object called Orbiter. When the user clicks, a new Orbiter is created with the mouse coordinates and it is added to an array of orbiters. On each loop, we will cycle through the array of Orbiters and update each one. I'm not quite sure why you are translating the whole canvas and I'm not sure I understand the formulas, but if the black whole will not be rotating, I think that each orbiter should be rotating the canvas. I also replaced your setInterval with a more appropriate requestAnimationFrame

Upvotes: 1

Related Questions