Search code examples
javascriptcanvasaddeventlistenermouse-position

Live update of rgba using clientX/clientY?


The code below works until line 47 is replaced with line 48 (i.e. calculating the fillStyle). For some reason attempting to use clientY to calculate the blue portion of the rgba doesn't work, whereas calculating the alpha is not a problem.

<!DOCTYPE html>
<html>

<head>
    <title> My Animation </title>
</head>

<body>
    <canvas id="myCanvas" height="768" width="1200"></canvas>
</body>
<script>
    var mainCanvas = document.getElementById("myCanvas");
    var ctx = mainCanvas.getContext('2d');
    var canvasWidth = mainCanvas.width;
    var canvasHeight = mainCanvas.height;
    // the array of squares
    var squares = [];

    var mouseX = 1200;
    var mouseY = 768;
    var putPoint = function (e) {
        // update mouse
        mouseX = e.clientX;
        mouseY = e.clientY;
    }
    mainCanvas.addEventListener("click", putPoint);

    for (i = 0; i < 100; i++) {
        squares.push(new Square());
    }

    function Square() {
        this.x = Math.random() * 1024;
        this.y = Math.random() * 768;
        this.inc = Math.random() * 360;
        this.angle = 0;
        this.speed = Math.random() * 6 - 3;
    }

    Square.prototype.update = function () {
        ctx.save();
        ctx.translate(this.x, this.y);
        ctx.rotate(this.angle);
        ctx.beginPath();
        ctx.rect(-25, -25, 50, 50);
        ctx.closePath();
//        ctx.fillStyle = "rgba(255,0," + 150 + "," + mouseX/1024 + ")";
        ctx.fillStyle = "rgba(255,0," + mouseY/768*255 + "," + mouseX/1024 + ")";
        console.log(mouseY/768*255);
        ctx.fill();
        ctx.restore();
        this.inc = this.inc + this.speed;
        this.angle = this.inc % 360 / 57.2958;

    }

    function draw() {
        ctx.clearRect(0, 0, 1024, 768);
        for (var i = 0; i < squares.length; i++) {
            var myBox = squares[i];
            myBox.update();
        }
        requestAnimationFrame(draw);
    }

    draw();
</script>

Solution

  • The Red, Green and Blue values should be integers. You can make them integers by using the Math.floor() method. Below is your fixed code.

    <!DOCTYPE html>
    <html>
    
    <head>
        <title> My Animation </title>
    </head>
    
    <body>
        <canvas id="myCanvas" height="768" width="1200"></canvas>
    </body>
    <script>
        var mainCanvas = document.getElementById("myCanvas");
        var ctx = mainCanvas.getContext('2d');
        var canvasWidth = mainCanvas.width;
        var canvasHeight = mainCanvas.height;
        // the array of squares
        var squares = [];
    
        var mouseX = 1200;
        var mouseY = 768;
        var putPoint = function (e) {
            // update mouse
            mouseX = e.clientX;
            mouseY = e.clientY;
        }
        mainCanvas.addEventListener("click", putPoint);
    
        for (i = 0; i < 100; i++) {
            squares.push(new Square());
        }
    
        function Square() {
            this.x = Math.random() * 1024;
            this.y = Math.random() * 768;
            this.inc = Math.random() * 360;
            this.angle = 0;
            this.speed = Math.random() * 6 - 3;
        }
    
        Square.prototype.update = function () {
            ctx.save();
            ctx.translate(this.x, this.y);
            ctx.rotate(this.angle);
            ctx.beginPath();
            ctx.rect(-25, -25, 50, 50);
            ctx.closePath();
            //ctx.fillStyle = "rgba(255,0," + 150 + "," + mouseX/1024 + ")";
    
            ctx.fillStyle = "rgba(255,0," + Math.floor(mouseY/768*255) + "," + mouseX/1024 + ")";
            
            //console.log(mouseY/768*255);
            ctx.fill();
            ctx.restore();
            this.inc = this.inc + this.speed;
            this.angle = this.inc % 360 / 57.2958;
    
        }
    
        function draw() {
            ctx.clearRect(0, 0, 1024, 768);
            for (var i = 0; i < squares.length; i++) {
                var myBox = squares[i];
                myBox.update();
            }
            requestAnimationFrame(draw);
        }
    
        draw();
    </script>