Cannot read property 'getContext' of null (no jQuery) - javascript

I'm trying to make a game with canvas but I have a problem. my problem is with the const ctx = canvas.getContext("2d");
I have the error Cannot read property 'getContext' of null
I looked at the other posts nothing helped my problem
(I don't use jquery)
thank you in advance for your future answers <3
Here is my HTML code and JS CODE :
<html lang="fr">
<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>Human Run</title>
<link href="./style.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Human Run</h1>
<div class="score-container">
<div id="bestScore"></div>
<div class="currentScore"></div>
</div>
</header>
<canvas class="landscape" id="fond" width="350" height="416"></canvas>
<canvas class="ground" id="sol" width="350" height="150"></canvas>
<script src="./script.js" type="text/javascript" ></script>
<script src="./ground.js" type="text/javascript" ></script>
</body>
</html>
JS CODE :
const canvas = document.getElementById('sol');
const ctx = canvas.getContext("2d");
const img = new Image();
img.src = '.media/ground2.png';
// réglages général
const speed = 6.2;
const render = () => {
index++;
// background
ctx.drawImage(img, 0, 0, canvas.width, canvas.height, -((index * (speed / 2)) % canvas.width) + canvas.width, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvas.width, canvas.height, -((index * (speed / 2)) % canvas.width), 0, canvas.width, canvas.height);
window.requestAnimationFrame(render);
}
img.onload = render;

Your problem seems to be simply that your javascript loads before your html, as a result, your javascript tries to use an element("sol") that does not exist at the time because it is not there yet. Two solutions either put async on your javascript <script> tag
https://www.w3schools.com/tags/att_script_async.asp
or surround your code with document.addEventListener("DOMContentLoaded",()=>{/* your code goes here*/});
https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event
document.addEventListener("DOMContentLoaded",()=>{
const ctx = sol.getContext("2d");
const img = new Image();
let index = 0;
img.src = 'http://fc04.deviantart.net/fs70/i/2012/014/c/9/rpg_floor_tiles_02_by_neyjour-d4me7dx.jpg';
// réglages général
const speed = 6.2;
const render = () => {
index++;
// background
ctx.drawImage(img, 0, 0, sol.width, sol.height, -((index * (speed / 2)) % sol.width) + sol.width, 0, sol.width, sol.height);
ctx.drawImage(img, 0, 0, sol.width, sol.height, -((index * (speed / 2)) % sol.width), 0, sol.width, sol.height);
window.requestAnimationFrame(render);
}
img.onload = render;
});
<header>
<h1>Human Run</h1>
<div class="score-container">
<div id="bestScore"></div>
<div class="currentScore"></div>
</div>
</header>
<canvas class="landscape" id="fond" width="350" height="416"></canvas>
<canvas class="ground" id="sol" width="350" height="150"></canvas>

Related

How to copy PIXI's view into another canvas

In theory it should be as easy as :
//targetCanvas is a canvas node
//app is instance of PIXI.Application
targetCanvas.drawImage(app.view, 0, 0);
But, trust me, It doesn't work!
Sometime (yes, I said sometime) it does work if I add some delay before copying the image into the targetCanvas. ... So, I wonder if there is an asynchronous process happening when PIXI is rendering... but I can not find this information in PIXI's documentation.
var loadImage = async function(imgPath) {
return new Promise((resolve, reject) => {
var img = document.createElement("img");
img.onload = ()=> {
resolve(img);
}
img.src = imgPath;
})
}
var canvasTag = document.querySelector("#canvasVideo");
var canvasCtx = canvasTag.getContext("2d");
var canvasResult = document.querySelector("#canvasResult");
var canvasResultCtx = canvasResult.getContext("2d");
var canvasWidth = canvasTag.width;
var canvasHeight = canvasTag.height;
var canvasWidth = 320;
var canvasHeight = 240;
const app = new PIXI.Application({
view: document.querySelector("#glCanvas"),
transparent: true,
width: canvasWidth,
height: canvasHeight
});
const container = new PIXI.Container();
const renderer = PIXI.autoDetectRenderer();
app.stage.addChild(container);
(async ()=> {
var imgTag = await loadImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAA5FBMVEX71DP///8AAAAUFRgAABb/2DT/2jT/3DX70yn70h3/3TX70RX70iT70y0AABURExj710T96J/+8cb84oT20DL//ff844n/+ur+9NL++OMLDxj85I784Hj72lr+997//vr966383mz96aPXti6ZgibvyjH97ru6nioACRfDpSj+8sn+9NT72VAdHBlDOxzqxjFwYCEsKBpNQx07MgxfURNzYReMeCR9ayJfUh/83nEnIQiskSOBbRoRDgONdxzUsystJgk9NhwhHxmwlikvKhpzYiFHPA4dGAa+oCZSRhA0LAtCOA1YRGDzAAANp0lEQVR4nO2dWVvbuhaGlcFTbIUMzkASAxkhDE1LobsQIC3sckrP//8/R3EmD5IsWXKw6fkuekEfxXq9pLWWZA0gl7garXZtUu3W+06lYgMA7ErF6fea3cGk3Wok/3iQ5I+32oOmU7FMw7AsXYcQbAQh1HXLMkwDOPXB+WGSlUiKsFWr9qFpWF4urKCOQE2nW2slVJMkCFuTZgWZLQItwGkYdm+SBKV0wovupWnoPHQea5qVblt2heQS1no6n+0wttR7Nan+RyLheR1VT4BuI9Rge+fyqiWL8LArB28DqXePJNVMDmHNMeXhrSHNy4mUukkgbFV1Q6TvkQQNqyrBuQoTHtYNKwG8lSyjLswoSHjUl948/dLNnmDGI0R42DeTaJ5BxjshOwoQtnoJ22/HWBeIkLEJj7t74nMZjerxvgknMDn/gpMF48aOeISHl8Ze+ZYynHguJxZhdw8OJixodvdEeAH220B3ssDFPgib72LAleKYkZfwyH4vA65kVXgzck7CwTsacCVoDhIkbDj7d6FhGX2u2MhD2Nb3F+Np0rkcDgfhifneaBtB8yQJwl5qAJHMnnTCxuX7+tCgLIc1GWckPITp6II76ZAxbLARXiQyTSEmaLBNrTIR1tLUBXcymYYbLITpcaIBMblUBsLUAiLEqgzCFAMixOgULpJwkGZAFsQowpQDMvTFCMJJ2gGjPSqdMKVhwi+T/qGKStjOAiBCpGY3NMKjbAACaNEmxSmEjahFBqkRBJQxMYXwMm3JNlm6E4fwLl3DJbqsOj9hNQ1TMuwih0USYUbc6E4maSxFIGxkpw9upBMG/QRCJ4OEBG+DJ8xYJ1zJwCfhWMLMdcKV8LkNlhBkJdT7BfEwmL/VsxQJvbKabITn2WyjS+FCBoYwe250K1w7Df+pmdU2uhSmnYYIszJkIijsT0OEl9n0oxvByyjCkyzGeq+M4LRNgPA4w25mLXhMJexm2c2sZHVphC1xN6OoWqmkqcr+CgZltiiEPdFGqiqnv34Wrj59G3JWVVGH3z5dFX7+OgWqYB30OpnwUNCEivbyXCx2Dg46xfL1UOMoqQ2vy25B9O9cE7Sj34g+wr6YCZXxdbFTWKtTHrEbQx2VtwUPip/GYoj6HYlQMNgrs6tiwaPiZ1ZE9bOvYPlqJoboC/teQrFeqIwPOoWCH5GtoWp+wELh7ErMinofTyjoSLXrciGg4ogFURsVgwXPPvF04rDMQyxhXciEmHoixGG0LZQhriDTuyHK6053hC2hfE2ZFQ/CFT27ju6K2qezcMGDolhXtBoYwqpQOqP9wlgC2WIaVVFlii/I2IcJsqoYQkEThjrh2ohRFdWuMSZEKgsaMUw4ESJUn7CWiO6J2F7oFvwmlNsYtRChIzQuVL504lVUfSAQdp5F6gOgEyQUS9iIligcXNGbqXaFcVCrd7MQaqbbgLEh7AqFChUXKtYVpfYn5IKJBTmyPoz0boBQLCPVvuPdxbKiL1TCFyLh2XexqK/7CWtikxcaLhiuCR9opiB2w2VIFCM0zn2Egikpua0VOtR4oV0TPNTy3cxE6rTNa1aEx2ImJDsaRPgv1Yb/UggZUj6adC+hYCMl5CWrxtaxKSXtDrF5M+RDdK1DIpDQSIFySiEsjiklx+QOXCieCtqw5yEUnJ6heERUUTohpSDVCzNI3xG2BaeBU0poXGwJxcJ9RCstUwnLybXS9QDDJawIfqugehp6fvlMIRRL2zbfMJaEwvPA1Gjxs0Qpqf1MLlqspxWB8MDJFZnwjDqU1T4T071CUbhW7leaJaHYBM1SJXLgpifQlJS984VmfCbpzTWhaDdEFf2HPESgxm1KDy7+Izq9D2BlRSg2BbWqKNmZRrQ1m1xQ1JUiGS2XUDBlc0XMTaLGQMRxFz0XYtQycQOik2wRFY2yBDFZEB0eulpGRETYl/DlntSfDjqRRc/w1hfNu13Bvkso5bOvhp+Kip4xU79h303nWYIJ3dQUyPjuC0i+5qBIGzqtZGO7sAw/A9yYD4TT7rVU3MxucR7t8dU55t2wfA5gkXGOCE/kLE7AfbgoR854L4V5NweCM95bWQNE2JS0wEQNtdNOh+kzoDLuBPtw8UWOCZdZDRCc7PZIm/uHQh3W1Bkl7n7Esti3NY+ggwgl/RaS9uKtafGZuaWps+ei983MZQEu8zbQkLjMSxt+WTMelMs3NntXUuzv5XUD6BS/cK3iiJDVAHKCxVqK9nJddPVryDcyKA1/rQpen4ouNvHJbIELuUv1FG08/T0d2tzVVDR7iEqOpfIt52qAjLzbLwVpvwUpMmpAUjhMq6wJqGZ/vSVNVhWIziSmXHoXiE/SpFp6Hdxle113lOAdkJa0pVPQAZfvXYdkBS9B5b3rkLA+PmEFRE8zZFt/A+HHb6X/J8y6Kn9BPPzoOU0fyPhqkWLBHuh9bEK9+ReMDz/4GF+vfvh5mpME5tpSJaMGJH1cS6uMCyC6qzLlMlug8cH7YQNIWC+UYkE73vdD6XPvrM/lfrD7/ZB7wlSxGb7OJyF1yv3tW+8iwgFnR1TA17y8T5g8D57l87yI1gkiPOcLF0vAfH7xDlZU7tGDZ3wPNtrc62lWgPwvU1ylW/fBQy5Edz0N30J9ewWYv9+3u9HmqwfnuVYO69zr2tSH9XPyr/slVBebB1P3UQW0XtfGNX4abx6Uf9snojLcPPaRp9h6bSLXMm/1dIt4sz9vo+xe7JTnqcv9a9xrhEufd4jyP7vjpdj322dyxan1GmHOvM3eEuZf9+NulPEWkM+Hb9Z5c2Y16nSH+IdjVVBseSyY58um3C2IMfZbaKMd4n84I3AMqbMdIGfX3+634F0Wpb3tEPNT4V0RdKlDz8M4m8x2zwzvAEqxHz1PlbaOEKvSqfdt8plwt++Je++a4n2v+c/JuVSl5OkR+QfOd7nasB5v/6HX26AgvEjIjOrY2x++8j7Fs/+Qfw/pNktc6UnCIWRhlX77HsJ97pBnD2mMfcClB9/TfyykOxwV3Poewb1Xz7cPOMakqXrje37+diw3bvhcDNIp98/79nIfx5hwCyKiaCyvqWqzN/+Pj/jbiHUseqZCCPHHVBKjOn4I/PQTvy/zn6nAO5WxkhJ4z8jd/S6JM6pgFPzd2xjOenOll9DZJmoIMf9nqgr1R0W1Q3yxAMGGTOx8GiXYUJHu5/yLvLe/V5oF22dcwO1ZWBvCmEv2S5gKoSoNYxlSVaaYN8adyqwUOmMo7taZQOjfGvJpyHcUqaJqw6d73E89xYq04XOiYu+V1X7jquVCLoDGZkpVs6cPj/ifmcdLJTBnfcXeaOkb3gT0NhoCVaVk5oqC/ns4xzXOlaYxU149FyaMvR1YscMu1aPXh/nQLmnqktTdUKG4GysQmqaNZ6dPr5Syj3EH2NYAQyjwIVENO/hgVf97+zD/PZ0uhjN7NlxMp9OXp9uvUaXeYk+SGLhzE0WOVtAWUZWNo1HsFAl/9qXQhuCIlhpHIqNO70nC3jNoRY4RVlR82Igtns19Qene24LlnSOszsgekV+nIuNN7xG0Ms+CVoihkVu3tkhySz4LWvw8byXSqbJIdMLAZ0LpZ7KHRnbcenwRHGXSzmSXcb6CNruNpqBorojOhhgNCqGMuxEUDTcCYtRIqAO6sgJ3BAfvt5CxfAiNYufYYUKEvr4I3xqApNPvt5BxKtZSqrbgbawPQwkzINF3lMi7Z0ZBIyJ2yNupDPMB77iQSCjxriA0fFiMaEOHdeN8WijSJiL9kQJLKPe+JzR0txej2x8kupun6ViVOM8avIIFSyj9XjlkypIynM5HDzdvr1/vH/OPf17fbh5GL2jYKJMOCUIMTvhPidwN6A550ZjXJVK01YBY+lMY7137+HfnZff+QxsLg/vjRTbXfpsXzIQZvYe0imX5W++SzeB9wBDy3Qecvetkee90zuUG2UI08ZcB0whzvSxFRatH5CATZuk2S5KXiSBswKwgQnBMxqAQ5g4zEhWh0aJQ0Aizktvg7+NmIszVsoBIjBMshLlJ+hHNGh0hgjB3knZE8ySCIIow7YiRgNGE6UaMBmQgTDMiAyALYXrdjRmc/Y1LmNKgAc1zlsozEaKxVPoSOGhRAz0nYe4Ipm1IrANaqsZPmGtcpmswZTmUZDsWIRovpikPN+vRFeYmzFVT0xkhS5SIQZhrp6Qz6jo9145PmGs4aWiphkOYVZNAmIaWCslzTlIIc0eV9/WpFsBO3UskzOW672hGaOK+LskmzLXBe5nRsnkNGI/wvcwIzfAn7KQIc4f7d6rQdEKLEBIkRCMquN+maoGI6RjphLnjqrG/+K8Tvg0mSojif93cD6NuNrlivDTCXK51twdG3ewxjpMSIEQup5cwI+KL52BkESI71o3kfI5l1YXsJ4UQMVYtI4n4CA2rKtD/JBIiTRzpjVU3nbjxwS85hKhDdnWJ0QP9Vlew+20lixDpvGdIgdQNq8czxI2QREIUIWs99PZF+iRE5Xs11kkmJkklXKrdrJhWLEpEZ1a6MUYPdEknRGpN6rZhWDyU0DKMSnMiHBowSoJwqVat2jdMI9KaEOqWYer9ai0JuqWSInTVap80HYBAEakOPUs7EJduIbOZVsVpDs6TgnOVKOFKjVa7dtKt9/pOZSOnX+8OJucXLQkRPUr/A5yNC0f3lG+mAAAAAElFTkSuQmCC");
canvasCtx.drawImage(imgTag, 0, 0, canvasWidth, canvasHeight);
var bgSprite = PIXI.Sprite.from(imgTag);
app.stage.addChild(bgSprite);
canvasResultCtx.drawImage(document.querySelector("#glCanvas"), 0, 0);
})()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://pixijs.download/release/pixi.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<canvas id="canvasVideo" width="320" height="240" autoplay></canvas>
<canvas id="glCanvas" width="320" height="240" autoplay></canvas>
<canvas id="canvasResult" width="320" height="240" autoplay></canvas>
</body>
</html>
canvasVideo (left) is normal canvas with 2d context.
glCanvas (middle) is a PIXI's view
canvasResult (right) is a normal canvas where a PIXI view should be copied into.
We don't have any problem copying canvas into PIXI. (except the CORS prevents the webGL renders the image correctly)
But, as you can see, the third canvas is blank. I wonder if there is any solution to this issue... without using PIXI's ticker or setTimeout?
You don't need to use the PIXI ticker or a custom timer (requestAnimationFrame as in your own response) to render to the canvas. There's the possibility to simply call app.render() in a synchronous way after the desired elements are added to the stage.
On top of that, if you want to prevent having a running application that renders on each frame, you may want to add autoStart: false to your Application config.
var loadImage = async function(imgPath) {
return new Promise((resolve, reject) => {
var img = document.createElement("img");
img.onload = ()=> {
resolve(img);
}
img.src = imgPath;
})
}
var canvasWidth = 320;
var canvasHeight = 240;
const app = new PIXI.Application({
view: document.querySelector("#glCanvas"),
transparent: true,
width: canvasWidth,
height: canvasHeight,
autoStart: false,
});
(async () => {
var imgTag = await loadImage("data:image/png;base64,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");
var bgSprite = PIXI.Sprite.from(imgTag);
app.stage.addChild(bgSprite);
app.render();
})()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://pixijs.download/release/pixi.js"></script>
<title>Document</title>
</head>
<body>
<canvas id="glCanvas" width="320" height="240"></canvas>
</body>
</html>
The ticker is not used for non-animated sprites, but apparently pixi still needs ONE frame to draw everything before you can copy it.
I was able to solve your issue with one requestAnimationFrame
(async ()=> {
var imgTag = await loadImage("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAA5FBMVEX71DP///8AAAAUFRgAABb/2DT/2jT/3DX70yn70h3/3TX70RX70iT70y0AABURExj710T96J/+8cb84oT20DL//ff844n/+ur+9NL++OMLDxj85I784Hj72lr+997//vr966383mz96aPXti6ZgibvyjH97ru6nioACRfDpSj+8sn+9NT72VAdHBlDOxzqxjFwYCEsKBpNQx07MgxfURNzYReMeCR9ayJfUh/83nEnIQiskSOBbRoRDgONdxzUsystJgk9NhwhHxmwlikvKhpzYiFHPA4dGAa+oCZSRhA0LAtCOA1YRGDzAAANp0lEQVR4nO2dWVvbuhaGlcFTbIUMzkASAxkhDE1LobsQIC3sckrP//8/R3EmD5IsWXKw6fkuekEfxXq9pLWWZA0gl7garXZtUu3W+06lYgMA7ErF6fea3cGk3Wok/3iQ5I+32oOmU7FMw7AsXYcQbAQh1HXLMkwDOPXB+WGSlUiKsFWr9qFpWF4urKCOQE2nW2slVJMkCFuTZgWZLQItwGkYdm+SBKV0wovupWnoPHQea5qVblt2heQS1no6n+0wttR7Nan+RyLheR1VT4BuI9Rge+fyqiWL8LArB28DqXePJNVMDmHNMeXhrSHNy4mUukkgbFV1Q6TvkQQNqyrBuQoTHtYNKwG8lSyjLswoSHjUl948/dLNnmDGI0R42DeTaJ5BxjshOwoQtnoJ22/HWBeIkLEJj7t74nMZjerxvgknMDn/gpMF48aOeISHl8Ze+ZYynHguJxZhdw8OJixodvdEeAH220B3ssDFPgib72LAleKYkZfwyH4vA65kVXgzck7CwTsacCVoDhIkbDj7d6FhGX2u2MhD2Nb3F+Np0rkcDgfhifneaBtB8yQJwl5qAJHMnnTCxuX7+tCgLIc1GWckPITp6II76ZAxbLARXiQyTSEmaLBNrTIR1tLUBXcymYYbLITpcaIBMblUBsLUAiLEqgzCFAMixOgULpJwkGZAFsQowpQDMvTFCMJJ2gGjPSqdMKVhwi+T/qGKStjOAiBCpGY3NMKjbAACaNEmxSmEjahFBqkRBJQxMYXwMm3JNlm6E4fwLl3DJbqsOj9hNQ1TMuwih0USYUbc6E4maSxFIGxkpw9upBMG/QRCJ4OEBG+DJ8xYJ1zJwCfhWMLMdcKV8LkNlhBkJdT7BfEwmL/VsxQJvbKabITn2WyjS+FCBoYwe250K1w7Df+pmdU2uhSmnYYIszJkIijsT0OEl9n0oxvByyjCkyzGeq+M4LRNgPA4w25mLXhMJexm2c2sZHVphC1xN6OoWqmkqcr+CgZltiiEPdFGqiqnv34Wrj59G3JWVVGH3z5dFX7+OgWqYB30OpnwUNCEivbyXCx2Dg46xfL1UOMoqQ2vy25B9O9cE7Sj34g+wr6YCZXxdbFTWKtTHrEbQx2VtwUPip/GYoj6HYlQMNgrs6tiwaPiZ1ZE9bOvYPlqJoboC/teQrFeqIwPOoWCH5GtoWp+wELh7ErMinofTyjoSLXrciGg4ogFURsVgwXPPvF04rDMQyxhXciEmHoixGG0LZQhriDTuyHK6053hC2hfE2ZFQ/CFT27ju6K2qezcMGDolhXtBoYwqpQOqP9wlgC2WIaVVFlii/I2IcJsqoYQkEThjrh2ohRFdWuMSZEKgsaMUw4ESJUn7CWiO6J2F7oFvwmlNsYtRChIzQuVL504lVUfSAQdp5F6gOgEyQUS9iIligcXNGbqXaFcVCrd7MQaqbbgLEh7AqFChUXKtYVpfYn5IKJBTmyPoz0boBQLCPVvuPdxbKiL1TCFyLh2XexqK/7CWtikxcaLhiuCR9opiB2w2VIFCM0zn2Egikpua0VOtR4oV0TPNTy3cxE6rTNa1aEx2ImJDsaRPgv1Yb/UggZUj6adC+hYCMl5CWrxtaxKSXtDrF5M+RDdK1DIpDQSIFySiEsjiklx+QOXCieCtqw5yEUnJ6heERUUTohpSDVCzNI3xG2BaeBU0poXGwJxcJ9RCstUwnLybXS9QDDJawIfqugehp6fvlMIRRL2zbfMJaEwvPA1Gjxs0Qpqf1MLlqspxWB8MDJFZnwjDqU1T4T071CUbhW7leaJaHYBM1SJXLgpifQlJS984VmfCbpzTWhaDdEFf2HPESgxm1KDy7+Izq9D2BlRSg2BbWqKNmZRrQ1m1xQ1JUiGS2XUDBlc0XMTaLGQMRxFz0XYtQycQOik2wRFY2yBDFZEB0eulpGRETYl/DlntSfDjqRRc/w1hfNu13Bvkso5bOvhp+Kip4xU79h303nWYIJ3dQUyPjuC0i+5qBIGzqtZGO7sAw/A9yYD4TT7rVU3MxucR7t8dU55t2wfA5gkXGOCE/kLE7AfbgoR854L4V5NweCM95bWQNE2JS0wEQNtdNOh+kzoDLuBPtw8UWOCZdZDRCc7PZIm/uHQh3W1Bkl7n7Esti3NY+ggwgl/RaS9uKtafGZuaWps+ei983MZQEu8zbQkLjMSxt+WTMelMs3NntXUuzv5XUD6BS/cK3iiJDVAHKCxVqK9nJddPVryDcyKA1/rQpen4ouNvHJbIELuUv1FG08/T0d2tzVVDR7iEqOpfIt52qAjLzbLwVpvwUpMmpAUjhMq6wJqGZ/vSVNVhWIziSmXHoXiE/SpFp6Hdxle113lOAdkJa0pVPQAZfvXYdkBS9B5b3rkLA+PmEFRE8zZFt/A+HHb6X/J8y6Kn9BPPzoOU0fyPhqkWLBHuh9bEK9+ReMDz/4GF+vfvh5mpME5tpSJaMGJH1cS6uMCyC6qzLlMlug8cH7YQNIWC+UYkE73vdD6XPvrM/lfrD7/ZB7wlSxGb7OJyF1yv3tW+8iwgFnR1TA17y8T5g8D57l87yI1gkiPOcLF0vAfH7xDlZU7tGDZ3wPNtrc62lWgPwvU1ylW/fBQy5Edz0N30J9ewWYv9+3u9HmqwfnuVYO69zr2tSH9XPyr/slVBebB1P3UQW0XtfGNX4abx6Uf9snojLcPPaRp9h6bSLXMm/1dIt4sz9vo+xe7JTnqcv9a9xrhEufd4jyP7vjpdj322dyxan1GmHOvM3eEuZf9+NulPEWkM+Hb9Z5c2Y16nSH+IdjVVBseSyY58um3C2IMfZbaKMd4n84I3AMqbMdIGfX3+634F0Wpb3tEPNT4V0RdKlDz8M4m8x2zwzvAEqxHz1PlbaOEKvSqfdt8plwt++Je++a4n2v+c/JuVSl5OkR+QfOd7nasB5v/6HX26AgvEjIjOrY2x++8j7Fs/+Qfw/pNktc6UnCIWRhlX77HsJ97pBnD2mMfcClB9/TfyykOxwV3Poewb1Xz7cPOMakqXrje37+diw3bvhcDNIp98/79nIfx5hwCyKiaCyvqWqzN/+Pj/jbiHUseqZCCPHHVBKjOn4I/PQTvy/zn6nAO5WxkhJ4z8jd/S6JM6pgFPzd2xjOenOll9DZJmoIMf9nqgr1R0W1Q3yxAMGGTOx8GiXYUJHu5/yLvLe/V5oF22dcwO1ZWBvCmEv2S5gKoSoNYxlSVaaYN8adyqwUOmMo7taZQOjfGvJpyHcUqaJqw6d73E89xYq04XOiYu+V1X7jquVCLoDGZkpVs6cPj/ifmcdLJTBnfcXeaOkb3gT0NhoCVaVk5oqC/ns4xzXOlaYxU149FyaMvR1YscMu1aPXh/nQLmnqktTdUKG4GysQmqaNZ6dPr5Syj3EH2NYAQyjwIVENO/hgVf97+zD/PZ0uhjN7NlxMp9OXp9uvUaXeYk+SGLhzE0WOVtAWUZWNo1HsFAl/9qXQhuCIlhpHIqNO70nC3jNoRY4RVlR82Igtns19Qene24LlnSOszsgekV+nIuNN7xG0Ms+CVoihkVu3tkhySz4LWvw8byXSqbJIdMLAZ0LpZ7KHRnbcenwRHGXSzmSXcb6CNruNpqBorojOhhgNCqGMuxEUDTcCYtRIqAO6sgJ3BAfvt5CxfAiNYufYYUKEvr4I3xqApNPvt5BxKtZSqrbgbawPQwkzINF3lMi7Z0ZBIyJ2yNupDPMB77iQSCjxriA0fFiMaEOHdeN8WijSJiL9kQJLKPe+JzR0txej2x8kupun6ViVOM8avIIFSyj9XjlkypIynM5HDzdvr1/vH/OPf17fbh5GL2jYKJMOCUIMTvhPidwN6A550ZjXJVK01YBY+lMY7137+HfnZff+QxsLg/vjRTbXfpsXzIQZvYe0imX5W++SzeB9wBDy3Qecvetkee90zuUG2UI08ZcB0whzvSxFRatH5CATZuk2S5KXiSBswKwgQnBMxqAQ5g4zEhWh0aJQ0Aizktvg7+NmIszVsoBIjBMshLlJ+hHNGh0hgjB3knZE8ySCIIow7YiRgNGE6UaMBmQgTDMiAyALYXrdjRmc/Y1LmNKgAc1zlsozEaKxVPoSOGhRAz0nYe4Ipm1IrANaqsZPmGtcpmswZTmUZDsWIRovpikPN+vRFeYmzFVT0xkhS5SIQZhrp6Qz6jo9145PmGs4aWiphkOYVZNAmIaWCslzTlIIc0eV9/WpFsBO3UskzOW672hGaOK+LskmzLXBe5nRsnkNGI/wvcwIzfAn7KQIc4f7d6rQdEKLEBIkRCMquN+maoGI6RjphLnjqrG/+K8Tvg0mSojif93cD6NuNrlivDTCXK51twdG3ewxjpMSIEQup5cwI+KL52BkESI71o3kfI5l1YXsJ4UQMVYtI4n4CA2rKtD/JBIiTRzpjVU3nbjxwS85hKhDdnWJ0QP9Vlew+20lixDpvGdIgdQNq8czxI2QREIUIWs99PZF+iRE5Xs11kkmJkklXKrdrJhWLEpEZ1a6MUYPdEknRGpN6rZhWDyU0DKMSnMiHBowSoJwqVat2jdMI9KaEOqWYer9ai0JuqWSInTVap80HYBAEakOPUs7EJduIbOZVsVpDs6TgnOVKOFKjVa7dtKt9/pOZSOnX+8OJucXLQkRPUr/A5yNC0f3lG+mAAAAAElFTkSuQmCC");
canvasCtx.drawImage(imgTag, 0, 0, canvasWidth, canvasHeight);
var bgSprite = PIXI.Sprite.from(imgTag);
app.stage.addChild(bgSprite);
requestAnimationFrame(() => {
canvasResultCtx.drawImage(document.querySelector("#glCanvas"), 0, 0);
});
})()

How to save canvas which include image?

I am trying to save my canvas which include image. I was trying use toDataURL, but it doesn't work on this case. The canvas is work to input the image inside.
HTML
<img src="bg.png" id="toIMG" />
<canvas></canvas>
<img alt="UNCHANGED" id="getCtx">
<span>Why does the img doesn't change?</span>
JS
window.onload = function(){
var c, ctx, img, img2;
c = document.querySelector("canvas");
ctx = c.getContext("2d");
img = document.getElementById("toIMG");
ctx.drawImage(img, 0,0, c.width, c.height);
img2 = document.getElementById("getCtx");
img2.src = ctx.canvas.toDataURL("image/png");
}
Instead of running the function when window has loaded, run it when the img has loaded. Also, as #CrissCrossCrass has pointed out, toDataURL is a method of canvas but not context.
<!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>Static Template</title>
</head>
<body>
<img
id="toIMG"
src="https://source.unsplash.com/random/120x120"
crossorigin="anonymous"
/>
<canvas></canvas>
<img id="getCtx" />
<script>
var c = document.querySelector("canvas");
var img = document.getElementById("toIMG");
var img2 = document.getElementById("getCtx");
var ctx = c.getContext("2d");
img.onload = function() {
c.width = img.width;
c.height = img.height;
ctx.drawImage(img, 0, 0, c.width, c.height);
img2.src = c.toDataURL("image/png");
};
</script>
</body>
</html>
Also, you may want to set the crossOrigin attribute of the first img element to be anonymous to avoid tainted canvas. Read more about it
I tried that and actually it's working. Share if the console drops any error. Then i'll update my answer depending on it.

how to load image on canvas using Promise

i am trying to load images on a canvas from my local folder, this is my js script :
function loadElement(url) {
return new Promise((resolve) => {
const element = new Image();
element.addEventListener("load", () => {
resolve(element);
});
element.src = url;
});
}
//canvas
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
context.fillRect(0, 0, 50, 50);
loadElement("./tilesheet.png").then((element) =>
context.drawImage(element, 0, 0)
);
and my html script:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Surface</title>
<link rel="stylesheet" href="css/main.css" />
<script type="module" src="js/main.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>
but i get this error:
GET http://127.0.0.1:5500/public/tilesheet.png 404 (Not Found)
and i dont understand why.
Your code loads fine with a known good image:
function loadElement(url) {
return new Promise((resolve) => {
const e = new Image();
e.addEventListener("load", () => { resolve(e); });
e.src = url;
});
}
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
context.fillRect(0, 0, 50, 50);
loadElement("http://i.stack.imgur.com/UFBxY.png")
.then((e) => context.drawImage(e, 0, 0));
<canvas id="canvas"></canvas>
My guess the error is right your image is not there: 404 (Not Found)

Using multiple canvas with pdf.js

I would like to display in a html page 4 canvas and each of them correspond to a page of a pdf file.
I succeed to display 1 page in 1 canvas, but when I want to display the 4 it doesn't work : none of the pages are displayed.
What I'm doing wrong ?
EDIT :
I tried to solve the problem of the promise (I edited my code) but now I got another error : Error: Invalid page request pdf.js:2687:31 and here is the corresponding code (2697 is the line of the return) :
getPage: function WorkerTransport_getPage(pageNumber, capability) {
if (pageNumber <= 0 || pageNumber > this.numPages ||
(pageNumber|0) !== pageNumber) {
return Promise.reject(new Error('Invalid page request'));
}
Here is my code :
html file :
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="description" content="PDF Viewer"/>
<title>My page</title>
</head>
<body>
<body>
<canvas id="canvas1" width="300" height="300"></canvas>
<canvas id="canvas2" width="300" height="300"></canvas>
<canvas id="canvas3" width="300" height="300"></canvas>
<canvas id="canvas4" width="300" height="300"></canvas>
<script src="/assets/js/pdf.js"></script>
<script src="/assets/js/pdf.worker.js"></script>
<script src="/assets/js/pdf.latex.main.js"></script>
</body>
</html>
Javascript file (pdf.latex.main.js) :
PDFJS.disableStream = true;
var pdfFile;
PDFJS.getDocument('/assets/pdf/tempPDF.pdf').then(function (pdf) {
pdfFile = pdf;
for(var i = 1; i < 4; i++) {
var canvas = document.getElementById('canvas'+i);
var context = canvas.getContext('2d');
PDFJS.disableStream = true;
openPage(pdf, i, context);
}
});
function openPage(pdfFile, pageNumber, context) {
var scale = 5;
pdfFile.getPage(pageNumber).then(function (page) {
viewport = page.getViewport(scale);
// reference canvas via context
var canvas = context.canvas;
canvas.width = viewport.width;
canvas.height = viewport.height;
canvas.style.width = "100%";
canvas.style.height = "100%";
wrapper.style.width = Math.floor(viewport.width / scale) + 'pt';
wrapper.style.height = Math.floor(viewport.height / scale) + 'pt';
var renderContext = {
canvasContext: context
, viewport: viewport
};
page.render(renderContext);
});
}
You are using promises, so all your calls to the function in .then branch are done after your for loop is finished, i.e. with i equal to 3 (last iteration value). As a result, you're filling the same canvas 3 times. By the way, take a look at your for loop. It loops only 3 times. You may want to change loop condition to i<=4.
You should call PDFJS.getDocument before the loop, and call this loop from within promise.
I finally solved it, here is the solution :
pdf.latex.main.js
var pdfFile;
PDFJS.getDocument('/assets/pdf/tempPDF.pdf').then(function (pdf) {
pdfFile = pdf;
for(var i = 1; i <= 4; i++) {
var canvas = document.getElementById('canvas'+i);
var context = canvas.getContext('2d');
PDFJS.disableStream = true;
openPage(pdf, i, context);
}
});
function openPage(pdfFile, pageNumber, context) {
var scale = 5;
pdfFile.getPage(pageNumber).then(function (page) {
viewport = page.getViewport(scale);
// reference canvas via context
var canvas = context.canvas;
canvas.width = viewport.width;
canvas.height = viewport.height;
canvas.style.width = "50%";
canvas.style.height = "50%";
var renderContext = {
canvasContext: context
, viewport: viewport
};
page.render(renderContext);
});
}
index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="description" content="PDF Viewer" />
<title>My page</title>
</head>
<body>
<form action="pdf_latex_test.php">
<input type="submit" value="execute" /> </form>
</body>
<body>
<canvas id="canvas1" width="300" height="300"></canvas>
<canvas id="canvas2" width="300" height="300"></canvas>
<canvas id="canvas3" width="300" height="300"></canvas>
<canvas id="canvas4" width="300" height="300"></canvas>
<script src="/assets/js/pdf.js"></script>
<script src="/assets/js/pdf.worker.js"></script>
<script src="/assets/js/pdf.latex.main.js"></script>
</body>
</html>

HTML5 Canvas animation not showing up

I've been knocking my head against the keyboard trying to figure out why the animation from this tutorial is not showing up on the canvas correctly, if at all. In chrome it draws the leftmost part of the image on the canvas, but in safari it draws nothing at all.
I've tried different methods of delaying until the image loads, putting the script tag in various places in the html, no luck. Debugging in chrome shows no errors.
The source code for the animation is not quite the same as what he presents in the tutorial, I've tried to make sense of it. I've been at it for two days and you'll pinpoint it 30 seconds, I want to see this damn coin spin.
spriteSheet.jpg:
animation.html:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link href='http://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css" type="text/css" />
<title>Test Profile Page</title>
</head>
<body>
<header>
<h1>Hello</h1>
</header>
<nav>
<ul>
<li>Pictures</li>
<li>Animation?</li>
<li>Cartoon</li>
</ul>
</nav>
<section>
<img src="spriteSheet.jpg" />
<canvas id="coinAnimation"></canvas>
</section>
<footer>
</footer>
<script src="animation.js"></script>
</body>
</html>
animation.js:
window.onload = function () {
var spriteSheet = new Image();
spriteSheet.src = "spriteSheet.jpg";
//define sprite class
function sprite (options) {
var that = {},
frameIndex = 0,
tickCount = 0,
ticksPerFrame = options.ticksPerFrame || 0,
numberOfFrames = options.numberOfFrames || 1;
that.context = options.context;
that.width = options.width;
that.height = options.height;
that.image = options.image;
that.loop = options.loop;
that.update = function () {
tickCount += 1;
if (tickCount > ticksPerFrame) {
tickCount = 0;
// If the current frame index is in range
if (frameIndex < numberOfFrames - 1) {
// Go to the next frame
frameIndex += 1;
} else if (that.loop) {
frameIndex = 0;
}
}
};
that.render = function () {
// Clear the canvas
that.context.clearRect(0, 0, that.width, that.height);
// Draw the animation
that.context.drawImage(
that.image,
frameIndex * that.width / numberOfFrames,
0,
that.width / numberOfFrames,
that.height,
0,
0,
that.width / numberOfFrames,
that.height);
};
return that;
}
var canvas = document.getElementById("coinAnimation");
canvas.width = 100;
canvas.height = 100;
var coin = new sprite({
context: canvas.getContext("2d"),
width: 100,
height: 100,
image: spriteSheet
});
function gameLoop () {
window.requestAnimationFrame(gameLoop);
coin.update();
coin.render();
}
spriteSheet.addEventListener("load", gameLoop);
}
When you enter the width on your coin you need to enter the width of your entire image (which seems to be 440), not the width of a single frame. Along with that you need to set the numberOfFrames to 10:
var coin = new sprite({
context: canvas.getContext("2d"),
width: 440,
height: 100,
image: spriteSheet,
numberOfFrames: 10
});
Note when it find the width of a single frame it does width/numberOfFrames to find that, this is why it will not work if you just enter 100. Now your coin should be spinning.
Fiddle Example.
If you want the slow the coin down you can add ticksPerFrame: 5 for example, the higher that is the slower it will go.

Categories

Resources