Ok so I'm creating a game with JavaScript Canvas Elements and such. I've been able to load in TONS of Images, but on a select few, JavaScript replies with Errors such as
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': No function was found that matched the signature provided.
Which makes NO SENSE at all, because the same code works in other places!?!
Here is an example I have in my code:
board.drawImage(document.getElementById("player_explode"), this.x, this.y);
Inside of an objects method, Player.die(), respectively.
Does anyone know why this behaviour is coming about? I'm getting very frustrated about it...
Here is a JSFiddle to demonstrate, alonside all the code.
Player.die() is located on line[242].
The problem was the way that I was loading my Images, I should've been doing:
var image = new Image();
image.src = "imagesource.jpg";
But instead I was get the elements by id from the document page.
Resources:
Explanation on loading images
Explanation on how html loads images
you should wait all elements load,so do like this:
window.onload=function(){
board.drawImage(document.getElementById("player_explode"), this.x, this.y);
}
For people in 2021 learning React, you have to call the context.drawImage() in the img.onload or nothing will be shown on the canvas! Here is a real world working example:
useEffect(() => {
canvasRef.current.width = mapXYWH.w * UNIT
canvasRef.current.height = mapXYWH.h * UNIT
const context = canvasRef.current.getContext("2d")
map.map(o => {
const img = new Image(o.width*UNIT,o.height*UNIT)
img.src = o.normal
img.onload = () =>
context.drawImage(img, (o.x-mapXYWH.x)*UNIT, (o.y-mapXYWH.y)*UNIT)
})
}, [map, mapXYWH])
See also: React -- Canvas Won't Draw Image
Related
I am trying to build a Vue App and I am new to Vue, I am trying to load an image at runtime in Js/Ts with the code below
console.log("code is being called");
let image = new Image();
image.onload = (event) => {
console.log("image loaded");
}
image.src = "static/prison_tileset.png";
The code works fine on a regular html file, in Vue however, the onload method isn't being called. The first console.log is being called. I am sure that the image is found because if I manipulate the path to something wrong on purpose I get an error that the file isn't being found. It's just that the onload event isn't being firied.
I'd be very happy if somebody could help me with that!
I've gotten it to work now! I will answer the question myself as best as I can. To use local assets in view you have to load them via Webpack like this:
const Logo = require("../assets/logo.png");
this.image.src = Logo;
If you also happen to use electron you have to set the webSecurity in your entry file to false for electron to be allowed to access local files.
I'm trying to resize an image that uses a base64 encoded source. To do this I'm trying to use the canvas element's 2d draw image method for a canvas that is the side I'd like to scale down to.
This is what my method looks like:
resizeImage (base64Image) {
let vm = this
return new Promise((resolve, reject) => {
// let img = document.createElement('img') // I've tried both with the Image constructor and with the document createElement function
let img = new Image()
img.onload = () => {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
canvas.width = vm.resizeDimensions.width
canvas.height = vm.resizeDimensions.height
// at this point, the `this` context is referring to the img element we created
// this is also the point at which I hit the type error
ctx.drawImage(this, 0, 0, vm.resizeDimensions.width, vm.resizeDimensions.height)
let uri = canvas.toDataUrl()
resolve(uri)
}
img.src = base64Image
})
},
The thing that's throwing me for a loop is that when I step through the code in the debugger and do my own type check, the image created (regardless of construction method) is one of the valid types for the drawImage method:
sorry for the crossing arrows. I tried recording a gif but the file size was too large to upload to stackoverflow.
There's definitely something I'm missing here. Why is a type error being thrown even though I can confirm that the garget is indeed the correct type?
A bit more information: This is a electron/vue prototype for a larger project. The code with this bug is in a branch and subfolder of the project here if you want to dig in: https://github.com/chris-schmitz/matching-game/tree/image-encoding-prototype-errors/prototypes/saving-and-encoding-images.
Update
Here's a screenshot of the contents of this within the onload callback:
Also, the gif I recorded of the error happening can be found here:
I'm not sure what I'm doing wrong in this problem. I'm using OpenProcessing and trying to put a canvas element within a container but I'm running into an Uncaught TypeError, Cannot read property "id"
I'm copying the same code from https://github.com/processing/p5.js/wiki/Positioning-your-canvas
function setup() {
var cnv = createCanvas(100, 100);
var x = (windowWidth - width) / 2;
var y = (windowHeight - height) / 2;
cnv.position(x, y);
background(255, 0, 200);
}
This is my code...
function setup() {
var cnv = createCanvas(500, 100);
cnv.id("hello");
cnv.position(0,0);
}
function draw() {
}
Here is a link to my sketch...
https://www.openprocessing.org/sketch/407956
It has something to do with OpenProcessing because your code works absolutely fine on p5 editor (and locally).
The createCanvas method returns an object so calling the id function on it should not return "Cannot read property 'id' of undefined" as it did on OpenProcessing so createCanvas possibly isn't returning anything, and it should return an object according to p5 documentation..
You can try positioning the canvas using css as described in p5 wiki by adding a stylesheet that uses flexible box layout or try not using OpenProcessing if possible.
The createCanvas() function is not returning anything. This doesn't jive with what's in the P5.js reference, so I understand your confusion.
My guess is that OpenProcessing uses a slightly modified version of P5.js, because it doesn't really require any positioning. The canvas is always centered in the screen.
If you're going to continue using OpenProcessing, then I'd stop worrying about positioning the canvas yourself. Or I'd search for existing sketches that reposition the canvas and see how they do it.
Even if the createCanvas() function returns soemthing, I'm not sure what the id() function is supposed to do in this case. Nothing in the link you posted uses that function. Nonetheless, it seems to work fine if I run it locally.
Background: For a university project I have been tasked with creating a Flappy Bird clone. Originally it worked fine, then as I began adding more images, they stopped loading within Chrome. Firefox was fine (unless I did a fresh reload, but every subsequent reload was fine).
I was making a new 'Sprite' object for each image and within that sprite object's initialiser I would create an Image object and assign the src. I eventually realised this was the problem, so I rearranged my structure like this:
var ent_player_img = new Image();
ent_player_img.onload = function()
{
window.ent_player = new Sprite(ent_player_img);
};
ent_player_img.src = "../images/ent_player.png";
I would assign ent_player.img to the new Image object within the constructor. However, this was throwing reference errors within my game loop.
To combat this I put all of the functions in my game loop that called these objects within an if statement.
if (typeof ent_player !== undefined)
{
//Draw image
}
And yet I was still getting the errors. Inside the if statement I used a console.log saying typeof ent_player which returned as undefined.
Very puzzled as to why this code was still running and causing issues, I used my debugger of choice (Firebug).
I put a breakpoint on the if statement, however, whenever I step through the code with the debugger it works perfectly. Correct outputs, etc. Then as soon as I try it again without the debugger, same issue.
Can anyone give me an idea as to why this is happening and how I can fix it?
Thank you very much.
Edit: Sprite constructor looks like this:
function Sprite(image)
{
this.img = image;
this.height = this.img.height;
this.width = this.img.width;
this.x = 0;
this.y = 0;
}
In my Greasemonkey script, when I obtain a handle on an HTMLImageElement I want to use with an HTML Canvas, I get the following error in Firefox's Error Console (I assume it's because it's enclosed in an XPCNativeWrapper):
Error: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE)
[nsIDOMCanvasRenderingContext2D.drawImage]
Putting GM_log() statements throughout my code, I have traced the image object I'm trying to use from it's initial assignment through until I try to use it with an HTML Canvas.
It's always wrapped in an XPCNativeWrapper:
[object XPCNativeWrapper [object HTMLImageElement]]
I've unwrapped the HTMLImageElement by obtaining reference to it with image.wrappedJSObject.
My canvas code:
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
Any ideas why Firefox is throwing the above component failure code?
I should have looked more thoroughly on Google.
image.wrappedJSObject;
Works.
var canvas = document.createElement("canvas").wrappedJSObject,
ctx = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
this is what i did. hope it helps
I just had the same problem. The error went away when I used an absolute/complete URL for the image. Also, as someone else had noted, make sure the image is loaded first of all, or just create a new Image() in javascript first of all.
Working example for firefox 3.6.16 (I had similar problem):
http://userscripts.org/scripts/review/106800