Javascript: image does not load on canvas - javascript

I am trying to use an image as the background of my canvas. However, I have a hard time to make the image load -- it always shows as blank:
<html>
<script>
var background = new Image();
background.src = "img/map.png";
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
window.onload = function() {
ctx.drawImage(background, 0, 0);
}
</script>
<body>
<canvas id="myCanvas" width="400" height="400"> </canvas>
</body>
</html>
However, if I put the following two lines into the window.onload function, then the image loads without any issue. what causes this issue? As I will use canvas and ctx in other functions, I really want to define them globally rather than individually define them in each function.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

you can still use them globally. As canvas is not available immediately you are not able to draw picture before on load.
<script>
var background = new Image();
background.src = "img/map.png";
var canvas;
var ctx ;
window.onload = function() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.drawImage(background, 0, 0);
} </script>

1) The first option is to declare the canvas and context and assign them values after the document has loaded
<!DOCTYPE html>
<html lang="en">
<head>
<title>Onload</title>
<script>
const background = new Image();
background.src = "img/map.png";
let canvas;
let ctx;
window.onload = function() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.drawImage(background, 0, 0);
}
</script>
</head>
<body>
<h1>Method One</h1>
<p>Defined variables globally and assign then after the load event is fired</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>
2) The second method would be to put the script block after the canvas element so that it is already loaded in the DOM when your javascript tries to access it.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Onload</title>
</head>
<body>
<h1>Method Two</h1>
<p>Put the script after the DOM element you wish to access</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
<script>
const background = new Image();
background.src = "img/map.png";
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
window.onload = function() {
ctx.drawImage(background, 0, 0);
}
</script>
</body>
</html>
I've used the new const and let keywords just to highlight the difference between these two approaches, although using var instead will work fine too. (see let and const)
If you want to avoid global variables then you might structure your code like this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Onload</title>
<script>
const background = new Image();
background.src = "img/map.png";
draw = context => {
context.drawImage(background, 0, 0);
}
window.addEventListener('load', () => {
const canvas = document.querySelector("#myCanvas");
const ctx = canvas.getContext("2d");
draw(ctx);
});
</script>
</head>
<body>
<h1>Refactor</h1>
<p>Add an event listener and pass in context to draw function</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>
It doesn't matter that I'm using arrow functions, or querySelector, I just prefer these newer methods. The point is to pass in the canvas context to any function that needs it draw(ctx).
The two lines of code creating the Image() and then setting the background had to be done before the document had finished loading, this is a bit of a fudge. What we really need to do is make sure that the image we are trying to set as the background has loaded before calling drawImage() Using images
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Onload</title>
<script>
draw = context => {
const background = new Image();
background.src = "img/map.png";
background.addEventListener('load', () => {
context.drawImage(background, 0, 0);
});
}
window.addEventListener('load', () => {
const canvas = document.querySelector("#myCanvas");
const ctx = canvas.getContext("2d");
draw(ctx);
});
</script>
</head>
<body>
<h1>Final</h1>
<p>Add an event listener to the image</p>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

Related

Get base64 data of image inside a canvas

I know this question is asked man times but my problem is this. I want to get data of image inside a canvas and get that! But when I change the image resource derived data does not change. In an other words it doesn't matter what image I use in my code. For best understanding my question my code is below.
<!DOCTYPE html>
<html>
<body>
<canvas id="viewport" style="border:1px solid #d3d3d3;"></canvas>
<script>
var canvas = document.getElementById('viewport'),
context = canvas.getContext('2d');
make_base();
function make_base()
{
base_image = new Image();
base_image.src = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png';
base_image.onload = function(){
context.drawImage(base_image, 0, 0);
}
}
const base64Canvas = canvas.toDataURL("image/jpeg").split(';base64,')[1];
document.write('<br>');
document.write(base64Canvas);
</script>
</body>
</html>
I the code above it does not matter what picture to use. The base64 data is same or every one. Any help?
you should capture the image after it has been loaded and drawn. this is asynchronous action so:
Update: please use an image locally or from an origin that allows CORS.
<!DOCTYPE html>
<html>
<body>
<canvas id="viewport" style="border:1px solid #d3d3d3;"></canvas>
<script>
var canvas = document.getElementById('viewport'),
context = canvas.getContext('2d');
make_base();
function make_base() {
base_image = new Image();
base_image.onload = function() {
context.drawImage(base_image, 0, 0);
const base64Canvas = canvas.toDataURL("image/jpeg").split(';base64,')[1];
console.log(base64Canvas);
}
base_image.crossOrigin = "anonymous"
base_image.src = 'https://picsum.photos/200';
}
</script>
</body>
</html>

How to display data from response in html canvas

I am trying to display a response fetched from an api in a html canvas, but for some reason the canvas does not display the text from the response. I inspected the element I can see in the dev tools that the data is displayed in the html but I can't see it on the screen, why is the data not visible and how can I display it properly in the canvas?
Here is my html:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="js/main.js"></script>
</body>
</html>
and my js:
var canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
canvas.width = 934;
canvas.height = 622;
var background = new Image();
background.src = 'assets/background.jpg';
background.onload = function () {
ctx.drawImage(background, 0, 0);
}
fetch('https://api/list')
.then(response => response.json())
.then(data => canvas.innerHTML = data.animals.name[0]);
I tried to display it using the fillText() method but it didn't work as well.
You have to use fillText method to draw text. And also, you made a typo. You have to use the context ctx where as you used the element canvas.
Change the line canvas.innerHTML = data.animals.name[0] to ctx.fillText(data.animals.name[0], 10, 50)

Why doesn't my image draw in Canvas ? No error in my code

I got this sample of code which i was working on it, i got a trouble with because my image angular doesn't appear on the web browser, i can't understand what's my mistake, thanks in advance for your help.
<html>
<script>
var canvas,context;
function init(){
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
monImg = new Image();
monImg.src="img/angular.png";
context.drawImage(monImg,300,300);
}
window.onload=init();
</script>
<body>
<canvas id="canvas" width="1920" height="1080"></canvas>
</body>
See this question.
You have to wait for the image to load before you do anything with it. The easiest way is:
monImg = new Image();
monImg.onLoad = function() {
context.drawImage(monImg, 300, 300);
}
monImg.src = "img/angular.png";
You need to add a handler for the Image onload where you call drawImage() such as:
<html>
<body>
<canvas id="canvas" width="1920" height="1080"></canvas>
</body>
<script>
var canvas,context;
function init(){
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
monImg = new Image();
monImg.src="img/angular.png";
monImg.onload = function() {
context.drawImage(monImg,300,300);
}
}
window.onload=init();
</script>
</html>

How to set BPG on background

Can I use a BPG image as a <div> or <body> background? background: url('bg.bpg'); doesn't work.
There is a Javascript decoder which allows .bpg images to be displayed in <img> tags, but I want to use one as a <body> background.
The Javascript BPG decoder works by converting the source .bpg file into an ImageData object, which can then be drawn to a canvas. So all you need to do is get the canvas as a PNG data string and set that as the body background image:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>BPG background example.</title>
<!-- Decoder script from http://bellard.org/bpg/ -->
<script src="bpgdec8a.js"></script>
<script>
"use strict";
function setBackground(filename)
{
// Create a hidden canvas with the same dimensions as the image.
var canvas = document.createElement("canvas");
canvas.style.visibility = "hidden";
canvas.width = 512;
canvas.height = 512;
document.body.appendChild(canvas);
// Create a drawing context and a BPG decoder.
var ctx = canvas.getContext("2d");
var img = new BPGDecoder(ctx);
// Attempt to load the image.
img.onload = function()
{
// Once the image is ready, draw it to the canvas...
ctx.putImageData(this.imageData, 0, 0);
// ...and copy the canvas to the body background.
document.body.style.background = "url('" + canvas.toDataURL("image/png") + "')";
};
img.load(filename);
}
</script>
</head>
<body onload="setBackground('lena512color.bpg');">
<p>Hello, World!</p>
</body>
</html>

Pixel modification on a Video frame in HTML5 canvas

I am in the process of building an app for my research and I am new to canvas. I am trying to make a video out of a set of images and I need to be able to dynamically change a particular frame. I was successful in making the video but unable to modify a particular frame when I reach it. Below is the code for the same.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Images with intervals</title>
</head>
<body>
<canvas id="myCanvas1" width="400" height="200" style="position:absolute;right:0; margin-right:auto; background-color:#bbb"></canvas>
<canvas id="myCanvas2" width="400" height="200" style="position:absolute;left:0; margin-left:auto; background-color:#666"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('myCanvas2');
var context = canvas.getContext('2d');
var i = 0;
var im1 = 'images/img1.png';
function drawScreen() {
context.drawImage(im1, 0, 0,50,50);
}
setInterval(function() {
var im = ['images/img1.png', 'images/img2.png', 'images/img3.png', 'images/img4.png', 'images/img5.png'];
// Create the image object
var img = new Image();
//alert(window["i"]);
// If the image is loaded draw it on canvas
img.addEventListener('load', function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
});
//alert(window["i"]);
// pass in the image source
img.src = im[i++];
alert(window["i"]);
// if the image is last, change it back to the first
i = i > im.length - 1 ? 0 : i;
//alert(window["i"]);
if(i==3)
{ drawScreen();
//alert(window["i"]);
}
}, 1000);
</script>
</body>
</html>
When the value of i=3(meaning in 3 seconds according to the setInterval function), I am trying to display another image 'im1' as an example, which I am unable to do. I am new with HTML5 and canvas. Any help and suggestions here is deeply appreciated.

Categories