简体   繁体   中英

Javascript, Access to canvas methods from a variable in a class

I am a little stumped. I am still new to Javascript, so some of how it works eludes me when it comes to classes and objects. I had a lot of related code that I got working in a simple javascript file, and it seemed natural to refactor it into a working class. That process is not going so well.

After a lot of Stackoverflow and Google and W3Cschool searches, I am now lost.

When building this class, it seemed natural to allow the calling environment to define a canvas context and pass that context to my class so it can work on it. However, because at the time the browser sees it, it is not defined yet. after doing some searching, I came up with the following:

function HexGrid () {
    this.canvas         = null;                 // (canvas Context)
    this.borderColor    = "#FF0000";            // Hex Border Color
    this.fillColor      = "yellow";             // Hex Fill Color
    this.hexSize        = 20;                   // Hex Size Default

    // Draw a hex using Offset Coordinates.
    // Lets do Offset first, this should be the easiest.
    // “odd-q” vertical layout
    this.O_hex = function (x, y) {
        var width = this.HexSize * 2;
        var Horz = 3 / 4 * width;
        var Vert = Math.sqrt (3) / 2 * width;
        var Hpos = x * (Horz);
        var Vpos = (y * Vert) + ( (x%2)*(Vert/2) );
        this.drawHex(Hpos, Vpos);
    };  

    // Draw a Hex onto the Canvas.
    this.drawHex = function (in_x,in_y) {
        console.log ('Canvas = ' + this.canvas);
        var ctx = this.canvas;
        console.log ('ctx = ' + ctx);
        ctx.strokeStyle = this.borderColor;
        console.log ('ctx = ' + ctx);
        ctx.beginPath();
        for (var i = 0; i <= 6; i++) {
            angle = 2 * Math.PI / 6 * i
            x_i = in_x + size * Math.cos(angle);
            y_i = in_y + size * Math.sin(angle);
            if (i === 0) {
                ctx.moveTo (x_i, y_i);
            } else {
                ctx.lineTo (x_i, y_i);
            }
        }
        ctx.fillStyle=this.fillColor;
        ctx.fill();
        ctx.stroke();
    };  
}

////  TESTING CODE //////
function main () {
    Hex = new HexGrid;
    Hex.canvas = document.getElementById('canvas_1');

    for (var x = 0; x <= 10; x += 1) {
        for (var y = 0; y <= 10; y += 1) {
            Hex.O_hex (x,y);
        }
    }
}

And what I am getting now is the following in the Console:

Canvas = [object HTMLCanvasElement] hex-a27.js:24
ctx = [object HTMLCanvasElement] hex-a27.js:26
ctx = [object HTMLCanvasElement] hex-a27.js:28
Uncaught TypeError: Object #<HTMLCanvasElement> has no method 'beginPath' hex-a27.js:29
HexGrid.drawHex hex-a27.js:29
HexGrid.O_hex hex-a27.js:19
main hex-a27.js:53
onload Aquarius-a27.php:8

Which suggests to me that I have indeed got a canvas reference tucked into ctx, but it says it can't find the beginPath() method. I am concerned that my assignments are not even going into the canvas context. What is the correct way of accessing methods of DOM elements from Javascript that might not exist at the time the code is evaluated? (ie you created it later and passed it in, or assigned it to a property.)

Basically, I need some type of prototyping (thinking C'ish here) that says: "Yes, there will be a method called beginPath() and a property called strokeStyle, so, don't freak out if you can find them just yet..... or I just need another approach that works.

Thanks.

this should work:

this.drawHex = function (in_x,in_y) {
    console.log ('Canvas = ' + this.canvas);
    var ctx = this.canvas.getContext('2d');
    console.log ('ctx = ' + ctx);
    ctx.strokeStyle = this.borderColor;
    console.log ('ctx = ' + ctx);
    ctx.beginPath();
    for (var i = 0; i <= 6; i++) {
        angle = 2 * Math.PI / 6 * i
        x_i = in_x + size * Math.cos(angle);
        y_i = in_y + size * Math.sin(angle);
        if (i === 0) {
            ctx.moveTo (x_i, y_i);
        } else {
            ctx.lineTo (x_i, y_i);
        }
    }
    ctx.fillStyle=this.fillColor;
    ctx.fill();
    ctx.stroke();
  };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM