Snorre Rubin
Snorre Rubin

Reputation: 51

Draw temporary circle in canvas

I am trying to create a canvas, with a picture in it, where on click, a circle is created, to fade out over a certain time.

I am a total newbie to javascript, but this is what I have been able to cobble together so far: a canvas with the picture in it, and a function to draw a circle on click.

I would like to have the circle fade out, and a function that lets the user delete the last circle. Any ideas on how to do this?

Here is my code:

<section class="mbr-section mbr-section-nopadding mbr-figure--caption-outside-bottom" id="image1-1">
    <div class="mbr-figure">
        <img id="mave" height="0" src="assets/images/mave2.png">

<canvas id="imgCanvas" width="730" height="410" style="border:1px solid #d3d3d3;" onclick="draw(event)"></canvas>

<script>
window.onload = function() {
var c = document.getElementById("imgCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("mave");
ctx.drawImage(img,0,0);
}

var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");

function draw(e) {
    var pos = getMousePos(canvas, e);
    posx = pos.x;
    posy = pos.y;
    context.fillStyle = "#000000";
    context.beginPath();
    context.arc(posx, posy, 20, 0, 2*Math.PI);
    context.fill();
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
}
</script>

Upvotes: 2

Views: 1388

Answers (3)

JaAnTr
JaAnTr

Reputation: 906

Once something is drawn on the Canvas it is essentially forgotten about and is just some pixels. So if you want to interact with the shapes you've drawn you need to store them.

You could have an array of circles which holds circle objects.

var Circle = function (x, y, radius) {
    this.x = x; //Centre of the circle
    this.y = y; //Centre of the circle
    this.radius = radius;
};

var circlesArray = [];

Then when you want to add a circle you can create a new circle object and add it to the array.

circlesArray.push(new Circle(x, y, radius));

Then to draw them create a function that loops through the array and draw each circle

function drawCircles() {
    for (var i = 0; i < circlesArray.length; i++) {
        var circle = circlesArray[i];
        ctx.beginPath();
        ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2, false);
        ctx.stroke();
        ctx.closePath();
    }
}

Then to delete the last circle that was drawn you could use circlesArray.pop() to remove the last circle.

Once the last circle has been removed you can clear the Canvas with ctx.clearRect(0, 0, c.width, c.height); and recall the drawCircles() function.

Here is a good example of a fade function from another question - How to fade out an item in canvas

Upvotes: 1

Rex
Rex

Reputation: 143

In canvas after you draw, the pixels are on the canvas.

If you want the image still there and the circle will disappear, you need to keep draw the image.

setInterval(function(){
    draw();
},refreshRate);

When user click, save the position of the circle to a array.

draw image > draw circle (draw by the data of circle array)

after the circle fade out, remove the circle data that stored at the array and draw the image, then it the circle will not draw. If you want to remove last circle, just remove the last item of the list.

<canvas id="imgCanvas" width="730" height="410" style="border:1px solid #d3d3d3;"></canvas>

<script>
//game config
var canvas=document.getElementById("imgCanvas");
var canvasContext = canvas.getContext('2d');
var ch = canvas.height;
var cw = canvas.width;

var c=document.getElementById("myCanvas");
var img = new Image();
img.src = "mave2.png";

var circleArray = new Array();

// functions
window.onload = function(){
    setInterval(function(){
        canvasContext.drawImage(img,0,0,cw,ch);
        drawArrayCircle();
    },500);

    canvas.addEventListener("mousedown", function (evt) {
        var mousePos = calculateMousePos(evt);
        handleClickButton(mousePos);
    });
};


function saveCircleData(pos){
    circleArray.push(pos);
    console.log(circleArray);
}

function fadeOutCircle(){

}

function drawArrayCircle(){
    for(i=0;i<circleArray.length;i++){
         console.log(circleArray[i]);
        if (circleArray[i] != null) {
            if (!circleArray[i].opacity) {
                circleArray[i].opacity=1;
            } 

            drawOneCircle(i);
        }
    }
}

function drawOneCircle(index) {

    posx = circleArray[index].x;
    posy = circleArray[index].y;
    canvasContext.fillStyle = "#000000";
    canvasContext.beginPath();
    canvasContext.globalAlpha = circleArray[index].opacity;
    circleArray[index].opacity= circleArray[index].opacity -0.1;
    if (circleArray[index].opacity < 0) {
        circleArray.splice(index, 1);
    }
    canvasContext.arc(posx, posy, 20, 0, 2*Math.PI);
    canvasContext.fill();
    canvasContext.globalAlpha = 1.0;
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
}

function handleClickButton(mousePos) {
    saveCircleData(mousePos);
}


function calculateMousePos(evt) {
    var rect = canvas.getBoundingClientRect();
    var root = document.documentElement;
    var mouseX = evt.clientX -rect.left - root.scrollLeft;
    var mouseY = evt.clientY -rect.top - root.scrollTop;
    return {
        x:mouseX,
        y:mouseY
    };
}

</script>

Upvotes: 0

www0z0k
www0z0k

Reputation: 4434

First of all you'll need to store the circles somewhere.
var circles = [];

Then you'll have to run a function every N milliseconds to make the circles fade.

window.onload = function() {
    var c = document.getElementById("imgCanvas");
    var ctx = c.getContext("2d");
    var img = document.getElementById("mave");
    ctx.drawImage(img,0,0);
    setInterval(tick, 33);//this call
}

And a handler.

function tick(){
    draw();
}

Then modify the draw function.

function draw(e) {
    //clear the context
    context.clearRect(0, 0, canvas.width, canvas.height);
    //if we call it on click - create a new circle, add it to array
    if(e){
        var pos = getMousePos(canvas, e);
        circles.push({x : pos.x, y : pos.y, r : 20, alpha : 1});
    }
    //then fade out existing circles
    for(var i = circles.length - 1; i >= 0; i--){
        circles[i].alpha -= 0.005;
        if(circles[i].alpha <= 0){//cleanup dead ones
            circles.splice(i, 1);
            continue;
        }
        context.fillStyle = "rgba(0, 0, 0, " + circles[i].alpha + ")";
        context.beginPath();
        context.arc(circles[i].x, circles[i].y, circles[i].r, 0, 2*Math.PI);
        context.fill();
    }
}

Upvotes: 1

Related Questions