Daniel Kaplan
Daniel Kaplan

Reputation: 67440

drawImage doesn't work when I refer to an image in another javascript file

(I'll show the pure javascript below) I've got these two lines of code that are, in my mind, doing the exact same thing but one of them reports an error. This appears in a file named "Rendering.coffee". Here are the two lines (in coffeescript):

...
ctx.drawImage(document.getElementById("bg"), 0, 0)  #this works
ctx.drawImage(root.resources.bg, 0, 0)  #TypeError: Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement.
...

I assign root.resources.bg in another file named "Resources.coffee" like this:

root = exports ? this
root.resources = {}

root.resources.bg = document.getElementById("bg")

Here's the html that loads all the code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Canvas tutorial</title>

    <script src="Resources.js" type="text/javascript"></script>
    <script src="Rendering.js" type="text/javascript"></script>


    <style>
        canvas {
            border: 1px solid black;
        }
    </style>

</head>

<body onload="window['core'].startGame();">
<canvas id="canvas" width="640" height="480"></canvas>
<img id="bg" src="bg.png" style="display: none">

</body>
</html>

When I change the rendering code to this, I get no error:

root.resources.bg = document.getElementById("bg")
ctx.drawImage(root.resources.bg, 0, 0)

or

bg = document.getElementById("bg")
ctx.drawImage(bg, 0, 0)

That makes me think there's something more fundamentally wrong here. Can I only use img tags after I've already created the canvas context? If I change my "Resources.js" to print out the value of the bg variable it prints "null", but if I print it in the "Rendering.js" it prints [object HTMLImageElement] Why is it null in the "Resources.js"?

This is firefox, by the way.


Javascript

Rendering.js:

...
ctx.drawImage(document.getElementById("bg"), 0, 0);
ctx.drawImage(root.resources.bg, 0, 0);
...

Resources.js:

// Generated by CoffeeScript 1.6.2
(function() {
  var root;

  root = typeof exports !== "undefined" && exports !== null ? exports : this;

  root.resources = {};

  root.resources.bg = document.getElementById("bg");

}).call(this);

TL;DR: Why am I getting this error when I assign my image outside of my rendering function? #TypeError: Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement.


My First Attempt at a Solution

This worked for me, but I'm not sure if it's a good solution:

root = exports ? this
root.resources = {}

bgResource = undefined

root.resources.bg = ->
  if not bgResource
    bgResource = document.getElementById("bg")
  return bgResource

Then I call this as root.resources.bg()

Upvotes: 1

Views: 749

Answers (1)

user1693593
user1693593

Reputation:

You can try to solve this two ways -

Method 1

Move the scripts to the bottom of the file before the closing tag </body>. This way all DOM elements are loaded before any JavaScript is executed.

Method 2

Try to wrap all inits that are dependent on DOM elements in the window's load event inside the script files themselves in case you cannot or don't want to move them to the bottom:

window.addEventListener('load', function() {

    /// init the resource here...

}, false);

Upvotes: 1

Related Questions