0

I have this code:

var img = document.createElement("img");
img.src = "Images/test.png";
console.log(img);
img.addEventListener("load", start(img));

which is supposed to create a new image and show it onto a pattern inside a canvas element through "start()". But it shows a green box instead of an image. The only way to get it to work is to define an image with the same source in the HTML. When I try to make that image invisible, the image on the canvas becomes invisible too. this is confusing because my code was written to create a new element, but for some reason, it is being tied to the existing element on the page. Is there any way to fix this?

full code:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <title>Canvas Library</title>
    </head>
    <style type="text/css">
        .invisible {
            display: none;
        }
    </style>

    <body>
        <p id="text">Unknown</p>
        <canvas width="400" height="400" id="canvas"></canvas>
        <img src="Images/test.png" class="invisible"></img>
        <script type="text/javascript">
var Canvas = document.getElementById("canvas");
var label = document.getElementById("text");

function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}

console.log("" + rgbToHex(255, 100, 50));

var distance = function(x1, y1, x2, y2) {
    var a = Math.pow(x2 - x1, 2);
    var b = Math.pow(y2 - y1, 2);
    return Math.sqrt(a + b);
};

//Declare the Canvas Object
var canvasObj = function(src) {

    //Function to see if a line is colliding with a certain point Has an accuracy of about 1 pixel
    this.lineIsColliding = function(startX, startY, endX, endY, testX, testY) {
        const v1 = {
            x: endX - startX,
            y: endY - startY
        };
        const l2 = v1.x * v1.x + v1.y * v1.y;
        if (l2 === 0) {
            return false;
        } // line has no length so can't be near anything
        const v2 = {
            x: testX - startX,
            y: testY - startY
        };
        const u = (v1.x * v2.x + v1.y * v2.y) / l2;
        return u >= 0 && u <= 1 && Math.abs((v1.x * v2.y - v1.y * v2.x) / Math.sqrt(l2)) < 1;
    };
    var self = this;
    //The Canvas to draw on
    this.src = src;
    //The context of source(used for drawing)
    this.ctx = this.src.getContext("2d");
    //The Mouse Move Function
    this.showCoordinates = function(e) {
        console.log(e);
        label.innerHTML = "<b>x: </b>" + e.offsetX + " <b>y: </b>" + e.offsetY + ", " + self.lineIsColliding(358, 277, 365, 268, e.offsetX, e.offsetY);
    };
    //Show coordinates variable
    this.showCoordinatesBool = true;
    //The boolean to tell if we should use stroke
    this.useStroke = true;
    //The fill style and stroke style(can be color, pattern, or gradient)
    this.fillStyle = "#000000";
    this.strokeStyle = "#000000";
    //The Line cap style (can be butt, square, or round)
    this.lineCap = "butt";
    //The Stroke Weight (how wide the strokes are)
    this.strokeWeightVar = "default";
    //The corner style (how the corners are drawn)
    this.cornerStyle = "miter";
    //The Shadow Color
    this.shadowColorVar = "#000000";
    //The shadow Blur
    this.shadowBlurVar = 0;
    //The shadow Offsets
    this.shadowOffsetX = 0;
    this.shadowOffsetY = 0;
    //The style of the current font
    this.fontStyle = "normal";
    //The variant of the current font
    this.fontVariant = "normal";
    //The thickness of the current font
    this.fontThickness = "normal";
    //The height/size of the current font
    this.fontSize = 10;
    //The family of the current font
    this.fontFamily = "sans-serif";
    //Function to set the fill style
    this.fill = function(style) {
        this.fillStyle = style;
        this.ctx.fillStyle = style;
    };

    //Function to set the stroke style
    this.stroke = function(style) {
        this.useStroke = true;
        this.strokeStyle = style;
        this.ctx.strokeStyle = style;
    };

    //Function to delete the stroke
    this.noStroke = function() {
        this.useStroke = false;
    };

    //Function to draw a rectangle
    this.rect = function(x, y, width, height) {
        this.ctx.fillRect(x, y, width, height);
        if (this.useStroke) {
            this.ctx.strokeRect(x, y, width, height);
        }

    };

    //Function to draw a corner
    this.corner = function(style, centerX, centerY, x1, y1, x2, y2) {
        this.ctx.lineJoin = style;
        this.cornerStyle = style;
        this.ctx.beginPath();
        this.ctx.moveTo(x1, y1);
        this.ctx.lineTo(centerX, centerY);
        this.ctx.lineTo(x2, y2);
        this.ctx.stroke();
    };

    //Function to draw a hollow rectangle
    this.hollowRect = function(x, y, width, height) {
        this.ctx.strokeRect(x, y, width, height);
    };

    //Function to set the canvas background 
    this.background = function(style) {
        this.fillStyle = style;
        this.ctx.fillStyle = style;
        this.ctx.fillRect(0, 0, this.src.width, this.src.height);
    };

    //Function to draw a line
    this.line = function(startX, startY, endX, endY) {
        this.ctx.beginPath();
        this.ctx.moveTo(startX, startY);
        this.ctx.lineTo(endX, endY);
        this.ctx.stroke();
    };

    //Function to change line style
    this.lineCap = function(mode) {
        this.ctx.lineCap = mode;
        this.lineCap = mode;
    };

    //Function to change stroke weight
    this.strokeWeight = function(weight) {
        this.useStroke = true;
        this.ctx.lineWidth = weight;
        this.strokeWeightVar = weight;
    };

    //Function to clear a certain area
    this.clearArea = function(x, y, width, height) {
        this.ctx.clearRect(x, y, width, height);
    };
    //Turn the show coordinate function on
    this.enableCoordinates = function() {
        this.showCoordinatesBool = true;
        this.src.addEventListener("mousemove", this.showCoordinates);
    };
    /*Shadows*/

    //Set the shadow color
    this.shadowColor = function(color) {
        this.shadowColorVar = color;
        this.ctx.shadowColor = color;
    };
    //Set the shadow blur
    this.shadowBlur = function(blur) {
        this.shadowBlurVar = blur;
        this.ctx.shadowBlur = blur;
    };
    //Set the shadow offset
    this.shadowOffset = function(offsetX, offsetY) {
        this.shadowOffsetX = offsetX;
        this.shadowOffsetY = offsetY;
        this.ctx.shadowOffsetX = offsetX;
        this.ctx.shadowOffsetY = offsetY;
    };
    //Remove shadows
    this.noShadow = function() {
        this.shadowOffset(0, 0);
        this.shadowColor("#000000");
        this.shadowBlur(0);
    };

    //Function to see if a rectangle is colliding with a specific point
    this.rectIsColliding = function(rectX, rectY, rectWidth, rectHeight, testX, testY) {
        this.ctx.rect(rectX, rectY, rectWidth, rectHeight);
        return this.ctx.isPointInPath(testX, testY);
    };
    //Function that returns a custom linear gradient
    this.linearGradient = function(startX, startY, endX, endY, colorStops) {
        var gradient = this.ctx.createLinearGradient(startX, startY, endX, endY);
        for (var i = 0; i < colorStops.length; i++) {
            gradient.addColorStop(colorStops[i].location, colorStops[i].color);
        }
        return gradient;
    };
    //Function that returns a custom radial gradient
    this.radialGradient = function(x0, y0, r0, x1, y1, r1, colorStops) {
        var radialGradientVar = this.ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
        for (var i = 0; i < colorStops.length; i++) {
            radialGradientVar.addColorStop(colorStops[i].location, colorStops[i].color);
        }
        return radialGradientVar;
    };
    //Function that allows you to create a pattern
    this.pattern = function(image, mode) {
        var pat = this.ctx.createPattern(image, mode);
        return pat;
    };
    //Function that allows you to make text. Optional width parameter to limit the width of the text. Optional font parameter if you would like to set it manually.
    this.text = function(text, x, y, width, font) {
        if (font) {
            this.ctx.font = font;
        }
        else {
            this.ctx.font = this.fontStyle + " " + this.fontVariant + " " + this.fontThickness + " " + this.fontSize + "px " + this.fontFamily;
            console.log(this.ctx.font);
            console.log(this.fontStyle + " " + this.fontVariant + " " + this.fontThickness + " " + this.fontSize + "px " + this.fontFamily);
        }
        if (width) {
            this.ctx.fillText(text, x, y, width);
            if (this.useStroke) {
                this.ctx.strokeText(text, x, y, width);
            }
        }
        else {
            this.ctx.fillText(text, x, y);
            if (this.useStroke) {
                this.ctx.strokeText(text, x, y);
            }
        }

    };
    //Function that allows you to make hollow text. Optional width parameter to limit the width of the text. Optional font parameter if you would like to set it manually. Font Size MUIST be an INTEGER if you do not specify the font parameter
    this.hollowText = function(text, x, y, width, font) {
        if (font) {
            this.ctx.font = font;
        }
        else {
            this.ctx.font = this.fontStyle + " " + this.fontVariant + " " + this.fontThickness + " " + this.fontSize + "px " + this.fontFamily;
            console.log(this.ctx.font);
            console.log(this.fontStyle + " " + this.fontVariant + " " + this.fontThickness + " " + this.fontSize + "px " + this.fontFamily);
        }
        this.ctx.strokeText(text, x, y, width);
    };
    this.textWidth = function(text) {
        return this.ctx.measureText(text).width;
    };
};
//The following code is for testing purposes ONLY!
var start = function(image) {
    //Create a new canvas
    var myCanvas = new canvasObj(Canvas);
    //Set the Background Color
    myCanvas.background("#ff0000");
    //Set the fill color
    myCanvas.fill("#0000ff");
    //Set the Stroke Color
    myCanvas.stroke("#00ff00");
    //Draw a rectangle
    myCanvas.rect(164, 153, 50, 100);
    //Draw a hollow rectangle
    myCanvas.hollowRect(300, 300, 50, 50);
    //Disable the Stroke
    myCanvas.noStroke();
    //Draw a rectangle with no stroke
    myCanvas.rect(21, 18, 50, 50);
    //Change the Stroke color
    myCanvas.stroke("#ffff00");
    //Change the stroke weight
    myCanvas.strokeWeight(10);
    //Change the line cap
    myCanvas.lineCap("round");
    //Draw a line
    myCanvas.line(350, 30, 250, 80);
    //Draw a corner
    myCanvas.corner("miter", 50, 135, 100, 185, 100, 110);
    //Enable the Coordinates
    myCanvas.enableCoordinates();
    //Clear a space from the canvas
    myCanvas.clearArea(6, 245, 100, 100);
    //Set the Shadow Color
    myCanvas.shadowColor("black");
    //Set the shadow Blur
    myCanvas.shadowBlur(20);
    //Set the shadow offset
    myCanvas.shadowOffset(10, 0);
    //Set the stroke
    myCanvas.noStroke();
    //Set the fill color
    myCanvas.fill("orange");
    //Draw a rectangle
    myCanvas.rect(268, 167, 30, 30);
    //Remove the shadow
    myCanvas.noShadow();
    //Test if the rectangle is colliding with a specific point
    if (myCanvas.rectIsColliding(268, 167, 30, 30, 290, 170)) {
        myCanvas.fill("green");
        myCanvas.rect(358, 0, 50, 46);
    }
    else {
        myCanvas.fill("yellow");
        myCanvas.rect(362, 0, 50, 46);
    }


    //Test if a line is colliding with a certain point
    console.log("function returned: " + myCanvas.lineIsColliding(358, 277, 365, 268, 362, 271));
    if (myCanvas.lineIsColliding(358, 277, 365, 268, 362, 271)) {
        console.log("line is colliding!");
        myCanvas.line(358, 277, 365, 268);
    }
    else {
        console.log("line is not colliding!");

    }

    myCanvas.line(0, 0, 50, 10);

    //Color stop used for creating gradients
    var colorStop = function(location, color) {
        this.location = location;
        this.color = color;
    };

    console.log(distance(0, 0, 50, 10));

    myCanvas.fill(myCanvas.linearGradient(259, 77, 359, 127, [new colorStop(0.0, "green"), new colorStop(1.0, "blue")]));
    myCanvas.rect(259, 87, 100, 50);
    myCanvas.fill(myCanvas.radialGradient(309, 225, 10, 309, 225, 50, [new colorStop(0.0, "yellow"), new colorStop(1.0, "green")]));
    myCanvas.rect(259, 200, 100, 50);
    var pattern = myCanvas.pattern(image, "repeat");
    myCanvas.fill(pattern);
    myCanvas.rect(132, 81, 50, 100);

    myCanvas.fill(rgbToHex(0, 0, 0));
    //Setup text
    myCanvas.fontSize = 50;
    myCanvas.fontStyle = "oblique";
    myCanvas.fontVariant = "small-caps";
    myCanvas.fontThickness = 900;
    myCanvas.fontFamily = "sans";
    //Draw text
    myCanvas.text("Test", 200, 200);
    console.log(myCanvas.textWidth("Test"));
};


var img = document.createElement("img");
img.src = "Images/test.png";
console.log(img);
img.addEventListener("load", start(img));
</script>
    </body>

</html>

1
  • 1
    We don't see any canvas, and not any other existing image either?! Commented Oct 9, 2017 at 19:41

2 Answers 2

2

you try to use the img before it is loaded since you execute the start function right away.

use

img.addEventListener("load", function(){start(img);});

In other words you need to pass a function as the parameter to the addEventListener but you instead call a function and pass the result

Sign up to request clarification or add additional context in comments.

Comments

0

When you create an image that way you are creating it as a DOM element. You then need to add it to the DOM in the location you want it to show up at.

For example maybe:

document.body.appendChild(img)

That will cause the image to be loaded and subsequently for your start() function to be called.

Now I'm not sure that is how you load images for a Canvas to render but it should get you a little further.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.