在特定坐标下删除画布中的对象

时间:2018-08-21 12:48:06

标签: javascript

我想在单击上删除画布中已经生成的球,并减少底部的计数器,但是我的功能不起作用。这是我关于除球部分的代码。 是否可以使用div来获得相同的结果并促进球的移除?谢谢

    ball.onclick = function removeBalls(event) {


    var x = event.clientX;
    var y = event.clientY;

    ctx.clearRect(x, y, 100, 50);
    ctx.fillStyle = "#000000";
    ctx.font = "20px Arial";
    ctx.fillText("Balls Counter: " + balls.length - 1, 10, canvas.height - 10);

}

下面附上我的完整代码

// GLOBAL VARIBLES

var gravity = 4;
var forceFactor = 0.3; //0.3 0.5
var mouseDown = false;
var balls = []; //hold all the balls
var mousePos = []; //hold the positions of the mouse
var ctx = canvas.getContext('2d');
var heightBrw = canvas.height = window.innerHeight;
var widthBrw = canvas.width = window.innerWidth;
var bounciness = 1; //0.9

window.onload = function gameCore() {

    function onMouseDown(event) {
        mouseDown = true;
        mousePos["downX"] = event.pageX;
        mousePos["downY"] = event.pageY;
    }

    canvas.onclick = function onMouseUp(event) {

        mouseDown = false;
        balls.push(new ball(mousePos["downX"], mousePos["downY"], (event.pageX - mousePos["downX"]) * forceFactor,
            (event.pageY - mousePos["downY"]) * forceFactor, 5 + (Math.random() * 10), bounciness, random_color()));
        ball
    }

    function onMouseMove(event) {
        mousePos['currentX'] = event.pageX;
        mousePos['currentY'] = event.pageY;
    }
    function resizeWindow(event) {
        canvas.height = window.innerHeight;
        canvas.width = window.innerWidth;
    }

    function reduceBounciness(event) {

        if (bounciness == 1) {
            for (var i = 0; i < balls.length; i++) {


                balls[i].b = bounciness = 0.9;
                document.getElementById("btn-bounciness").value = "⤽ Bounciness";

            }
        } else {
            for (var i = 0; i < balls.length; i++) {
                balls[i].b = bounciness = 1;
                document.getElementById("btn-bounciness").value = " ⤼ Bounciness";
            }
        }

        return bounciness;
    }

    function reduceSpeed(event) {
        for (var i = 0; i < balls.length; i++) {
            balls[i].vx = velocityX = 20 + c;
            balls[i].vy = velocityY = 20 + c;
        }
    }

    function speedUp(event) {
        for (var i = 0; i < balls.length; i++) {
            balls[i].vx = velocityX = 120 + c;
            balls[i].vy = velocityY = 120 + c;
        }
    }

    function stopGravity(event) {
        if (gravity == 4) {
            for (var i = 0; i < balls.length; i++) {
                balls[i].g = gravity = 0;
                balls[i].vx = velocityX = 0;
                balls[i].vy = velocityY = 0;
                document.getElementById("btn-gravity").value = "►";
            }
        } else {
            for (var i = 0; i < balls.length; i++) {
                balls[i].g = gravity = 4;
                balls[i].vx = velocityX = 100;
                balls[i].vy = velocityY = 100;
                document.getElementById("btn-gravity").value = "◾";
            }
        }


    }


    ball.onclick = function removeBalls(event) {


        var x = event.clientX;
        var y = event.clientY;

        ctx.clearRect(x, y, 100, 50);
        ctx.fillStyle = "#000000";
        ctx.font = "20px Arial";
        ctx.fillText("Balls Counter: " + balls.length - 1, 10, canvas.height - 10);

    }


    document.getElementById("btn-gravity").addEventListener("click", stopGravity);
    document.getElementById("btn-speed-up").addEventListener("click", speedUp);
    document.getElementById("btn-speed-down").addEventListener("click", reduceSpeed);
    document.getElementById("btn-bounciness").addEventListener("click", reduceBounciness);
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mousemove", onMouseMove);
    window.addEventListener('resize', resizeWindow);

}

// GRAPHICS CODE
function circle(x, y, r, c) { // x position, y position, r radius, c color 
    //draw a circle
    ctx.beginPath(); //approfondire
    ctx.arc(x, y, r, 0, Math.PI * 2, true);
    ctx.closePath();
    //fill
    ctx.fillStyle = c;
    ctx.fill();
    //stroke
    ctx.lineWidth = r * 0.1; //border of the ball radius * 0.1
    ctx.strokeStyle = "#000000"; //color of the border 
    ctx.stroke();
}
function random_color() {
    var letter = "0123456789ABCDEF".split(""); //exadecimal value for the colors
    var color = "#"; //all the exadecimal colors starts with #
    for (var i = 0; i < 6; i++) {
        color = color + letter[Math.round(Math.random() * 15)];
    }
    return color;
}
function selectDirection(fromx, fromy, tox, toy) {
    ctx.beginPath();
    ctx.moveTo(fromx, fromy);
    ctx.lineTo(tox, toy);
    ctx.moveTo(tox, toy);

}

//per velocità invariata rimuovere bounciness
function draw_ball() {
    this.vy = this.vy + gravity * 0.1; // v = a * t
    this.x = this.x + this.vx * 0.1; // s = v * t
    this.y = this.y + this.vy * 0.1;

    if (this.x + this.r > canvas.width) {
        this.x = canvas.width - this.r;
        this.vx = this.vx * -1 * this.b;
    }
    if (this.x - this.r < 0) {
        this.x = this.r;
        this.vx = this.vx * -1 * this.b;
    }
    if (this.y + this.r > canvas.height) {
        this.y = canvas.height - this.r;
        this.vy = this.vy * -1 * this.b;
    }
    if (this.y - this.r < 0) {
        this.y = this.r;
        this.vy = this.vy * 1 * this.b;
    }

    circle(this.x, this.y, this.r, this.c);
}
// OBJECTS
function ball(positionX, positionY, velosityX, velosityY, radius, bounciness, color, gravity) {
    this.x = positionX;
    this.y = positionY;
    this.vx = velosityX;
    this.vy = velosityY;
    this.r = radius;
    this.b = bounciness;
    this.c = color;
    this.g = gravity;
    this.draw = draw_ball;

}

// GAME LOOP
function game_loop() {

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if (mouseDown == true) {
        selectDirection(mousePos['downX'], mousePos['downY'], mousePos['currentX'], mousePos['currentY']);
    }
    for (var i = 0; i < balls.length; i++) {

        balls[i].draw();
    }

    ctx.fillStyle = "#000000";
    ctx.font = "20px Arial";
    ctx.fillText("Balls Counter: " + balls.length, 10, canvas.height - 10);
}

setInterval(game_loop, 10);
* { 
    margin: 0px; padding: 0px;
 }
html, body { 
    width: 100%; height: 100%;

 }
#canvas { 
    display: block;
    height: 95%;
    border: 2px solid black;
    width: 98%;
    margin-left: 1%;
   
 }


#btn-speed-up, #btn-speed-down, #btn-bounciness, #btn-gravity{
    padding: 0.4%;
    background-color: beige;
    text-align: center;
    font-size: 20px;
    font-weight: 700;
    float: right;
    margin-right: 1%;
    margin-top:0.5%;

} 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Power Balls</title>
<link rel="stylesheet" type="text/css" href="css/style.css">

</head>

<body>
   
    <canvas id="canvas"></canvas>
  
    <input type="button" value="⤼ Bounciness" id="btn-bounciness"></input> 
    <input type="button" onclick="c+=10" value="+ Speed" id="btn-speed-up"></input> 

    <input type="button" value="◾" id="btn-gravity"></input> 
    <input type="button" onclick="c+= -10" value=" - Speed" id="btn-speed-down"></input> 
   
    
<script src="js/main.js"></script>
</body>

</html>

2 个答案:

答案 0 :(得分:0)

我看到两个问题:

  • # /path-to-your-project/gunicorn_conf:py bind = '0.0.0.0:8811' worker_class = 'sync' loglevel = 'debu' accesslog = '/var/log/gunicorn/access_log_yourapp' acceslogformat ="%(h)s %(l)s %(u)s %(t)s %(r)s %(s)s %(b)s %(f)s %(a)s" errorlog = '/var/log/gunicorn/error_log_yourapp' 不会被触发,因为/path-to-your-project/gunicorn -c gunicorn_conf.py forward_to_es:app 不是DOM对象。相反,您需要使用ball.onclick。检查用户是否单击了球还是在空白处以决定是删除还是创建球。
  • 要删除球,ball是不够的。这将从当前绘制的帧中清除球,但是对象仍保留在数组canvas.onclick中,因此将在下一帧中通过ctx.clearRect重新绘制。相反,您需要从阵列中完全删除被单击的球,例如G。 by using splice

否则,很好的演示! :)

答案 1 :(得分:0)

此操作无法完成,因为画布是即时模式API。您所能做的就是在顶部绘制,但这不可靠。

https://en.wikipedia.org/wiki/Immediate_mode_(computer_graphics)

您将必须将每个项目存储在单独的数据结构中,然后在发生更改时重新绘制。在您的情况下,有一个球阵列,因此在重绘整个阵列之前,应先删除单击的球。

每次删除某物时,请清除画布,然后重新绘制每个球。

如果速度太慢,可以进行一些优化。