Search code examples
javascripthtmlmouseeventlag

JavaScript mouse movement causing lag?


I am very new to coding in JavaScript and confused!

When you first run this code everything works fine. However, once you move for a little bit you start to realize it gets more and more laggy to where it is almost unplayable.

What is causing this?

How do I fix it?

<html>
<head>
    <title>Rotate</title>
    <script src="Tank.js"></script>
</head>
<body>
    <canvas id="canvas" style="border:1px solid #ccc" width="700" height="500">
    </canvas>
    <script>
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        var mouseX, mouseY;

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

        Tank.prototype.draw = function(){
            context.save();
            context.translate(this.x, this.y);
            context.rotate(this.angle);
            context.fillStyle = "green";
            context.arc(0,0,30,0,2*Math.PI);
            context.fill();
            context.fillStyle = "red";
            context.fillRect(0,-10,50,20);
            context.restore();
        }

        Tank.prototype.update = function(mouseX, mouseY){
            var dx = mouseX - this.x;
            var dy = mouseY - this.y;
            this.angle = Math.atan2(dy, dx);
        }

        canvas.addEventListener('mousemove', mouseMove);

        function mouseMove(evt){
            mouseX = evt.x;
            mouseY = evt.y;     
        }

        var tank = new Tank(350, 250);

        function gameLoop(){
            context.clearRect(0,0, canvas.width, canvas.height);
            tank.draw();
            tank.update(mouseX, mouseY);
        }

        setInterval(gameLoop,20);   
    </script>
</body>
</html>

Solution

  • You need to call context.beginPath() before starting new paths. Without this, your calls to arc build up the same path with more and more subpaths each frame, and so each successive frame is drawing a more complex shape. It's also taking more and more memory as time goes on.

    Fixed fiddle: https://jsfiddle.net/mmkzes7n/2/

    In this fiddle I also changed out setInterval for requestAnimationFrame, which I think is a good idea. You can read up about that and decide whether you want to make this same change or not. (You could then enhance it to only request an animation frame if a redraw is actually needed. At present this is only if the mouse position has moved, but as the game evolves I'm sure there will be more to it than that.)