Unable to display canvas background image upon webpage loading

Currently working on a JavaScript project to create a captcha display on a canvas. The issue I'm facing is that the background image does not load when the page initially opens. However, upon hitting the refresh button, it functions as intended. Here's the code snippet:

<script>
    var code = {};
    function canvas(){

         var canvas = document.getElementById('canvas');
           var ctx = canvas.getContext('2d');
           ctx.clearRect(0, 0, canvas.width, canvas.height);
            var background = new Image();
            background.src = "http://gazell.io/wp-content/uploads/2016/10/image011.png";
            ctx.drawImage(background, 0 ,0);
        var list = new Array('@','%','#','$','*','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9');                   
        var i;
        for (i=0;i<6;i++){
          var a = list[Math.floor(Math.random() * list.length)];
          var b = list[Math.floor(Math.random() * list.length)];
          var c = list[Math.floor(Math.random() * list.length)];
          var d = list[Math.floor(Math.random() * list.length)];
          var e = list[Math.floor(Math.random() * list.length)];
          var f = list[Math.floor(Math.random() * list.length)];
          var g = list[Math.floor(Math.random() * list.length)];
         }
       code.value = a  + b + c +  d + e + f + g;

       ctx.font = "italic 42px verdana";
       ctx.fillStyle="#FF9912";
       ctx.textAlign = "center";
       ctx.fillText(code.value, canvas.width/2,canvas.height/2);
    }

    window.onload = canvas();

    function ValidCaptcha(){
       //var string1 = document.getElementById('canvas').value;
       var string1 = document.getElementById('text').value;
       var string2 = code.value;
       if(string1 != null){
           if(string1 == string2){
           alert("true");
       }else{
           alert("false");
        }
       }  
    }     

</script>

Seeking assistance on displaying the canvas background immediately upon page load rather than relying on the refresh button.

<body onload="canvas();">
  <div class="box">
    <h1>Testing Captcha</h1>
    <canvas id="canvas" height="80" width="260"></canvas>
    <input id="text" type="text"></input>
    <button id="btn" onclick="canvas();">Refresh</button>
    <button type="button" value="Check" onclick="ValidCaptcha();">Submit</button>
  </div>
</body>

Answer №1

It appears that the issue you are facing stems from attempting to set the background image of the canvas before the image is fully loaded or its content is retrieved.

To resolve this issue, you should first create your image element and then draw on the canvas once the image has fully loaded.

I have provided a functional version of your code below. Additionally, ensure that the script is the last element in the HTML body.

<body onload="canvas();">
  <div class="box">
    <h1>Testing Captcha</h1>
    <canvas id="canvas" height="80" width="260"></canvas>
    <input id="text" type="text"></input>
    <button id="btn" onclick="canvas();">Refresh</button>
    <button type="button" value="Check" onclick="ValidCaptcha();">Submit</button>
  </div>

</body>
<script>
    var code = {};
    function canvas(){
            
     var createdImage = drawImage();
      //wait till image is loaded then draw canvas
      createdImage.onload = function(){
          var canvas = document.getElementById('canvas');
           var ctx = canvas.getContext('2d');
           ctx.clearRect(0, 0, canvas.width, canvas.height);
           
            ctx.drawImage(createdImage, 0 ,0);
        var list = new Array('@','%','#','$','*','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9');                   
        var i;
        for (i=0;i<6;i++){
          var a = list[Math.floor(Math.random() * list.length)];
          var b = list[Math.floor(Math.random() * list.length)];
          var c = list[Math.floor(Math.random() * list.length)];
          var d = list[Math.floor(Math.random() * list.length)];
          var e = list[Math.floor(Math.random() * list.length)];
          var f = list[Math.floor(Math.random() * list.length)];
          var g = list[Math.floor(Math.random() * list.length)];
         }
       code.value = a  + b + c +  d + e + f + g;

       ctx.font = "italic 42px verdana";
       ctx.fillStyle="#FF9912";
       ctx.textAlign = "center";
       ctx.fillText(code.value, canvas.width/2,canvas.height/2);
      }
       
    }

  var hiddenImg = document.getElementById('loadedImg');
  window.onLoad = canvas();
  
   

    function ValidCaptcha(){
       //var string1 = document.getElementById('canvas').value;
       var string1 = document.getElementById('text').value;
       var string2 = code.value;
       if(string1 != null){
           if(string1 == string2){
           alert("true");
       }else{
           alert("false");
        }
       }  
    } 
  //Draw image in seprate method
  function drawImage(){
     var background = new Image();
     background.src = "https://rrraul.co/wp-content/uploads/2017/06/projpanel_illust_random-1.jpg";
    
    return background;
  }

</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing a JavaScript array by including a numerical value

Here is my original dataset... [{ month: 'Jan', cat: 'A', val: 20 },{ month: 'Jan', cat: 'B',' val: 5 },{ month: 'Jan', cat: &ap ...

Tips for troubleshooting objects within an Angular template in an HTML file

When I'm creating a template, I embed some Angular code within my HTML elements: <button id="btnMainMenu" class="button button-icon fa fa-chevron-left header-icon" ng-if="(!CoursesVm.showcheckboxes || (CoursesVm.tabSelected == 'curren ...

Learn how to bring in images using props within React and incorporate the 'import' pathway

These are the props I am passing: const people=['Eliana','Stefania','Ahmed'] { people.map(function(name, index){ return <Person item={index} name={name}/>; }) } import Eliana from '../assets/imgs/people ...

"Utilizing Node.js and Express to return JSONP data based on

For some reason, my Express application is giving me a strange result when using res.jsonp. It looks like this: /**/ typeof jsonp1406719695757 === 'function' && jsonp1406719695757({"published":true,"can_add_to_cart":true,"updated_at":"20 ...

What is the secret to creating a button that can sort text and another button that flips the word density in my content?

I'm not a fan of having something like this because it's displeasing to the eye: https://i.stack.imgur.com/3F4sp.jpg Instead, I prefer my word density to be more organized and structured. How can I achieve this? Sort by highest word density fi ...

Using Typescript to implement a conditional return type and ensuring that the value types are consistent together

I am working with a useSelectedToggle hook that helps in connecting the UI state to the open/closed status of a dialog where it will be displayed. The toggle defines the value as (T) when it is open, and null when it is closed. How can I enforce stricter ...

How to access a particular tab in Bootstrap 5 using an external link

Is there a way to direct users to a specific tab upon clicking a link on another page? Check out the example below: <div class="products-btn"> <a href="products.html#pills-profile">view all</a> </div> On Pro ...

Nested ng-repeat for dynamic variable rendering

I am facing an issue where I have a nested ng-repeat directive. I am attempting to create a dynamic second ng-repeat, using a key from the first one, but the current syntax is not working. Is there a different way to achieve this? Perhaps a different nota ...

Having trouble with Angular JS's ngRoute feature not functioning properly

I've been struggling with my ngRoute implementation. I seem to be unable to load the 'ngRoute' module for some reason. Whenever I run this code, I just end up with a blank page. Below is my app.js file: var app = angular.module('tutor ...

Encountering a fresh issue after updating to TS version 4.4.3 while accessing properties of the top "Object may be 'null'."

After upgrading my project to TypeScript 4.4.3 from 3.9.9, I encountered a change in the type declarations for the top property. My project utilizes "strictNullChecks": true, in its configuration file tsconfig.json, and is browser-based rather t ...

When attempting to access /test.html, Node.js server returns a "Cannot GET"

Embarking on the journey of diving into Pro AngularJS, I have reached a point where setting up the development environment is crucial. This involves creating an 'angularjs' directory and placing a 'test.html' file in it. Additionally, o ...

Issues with collision detection between circles within grouped clusters

I am currently developing a game with circle-shaped gameobjects, similar to agar.io. I have implemented a collision system for these objects, which works well most of the time. However, when there are more than two objects in close proximity, the game beco ...

Sending a unicode PHP variable to JavaScript is a breeze

I am attempting to transfer the titles and excerpts of Persian Wordpress posts to JavaScript. Below is the code in a .php script file: function change(){ document.getElementById("link").innerHTML = '<a href="$links[2]">$titles[2]< ...

Incorrect interpretation of JavaScript object

To display some structured data on my JADE page, I created a JSON-like object containing variables, text, and JavaScript objects. Here is an example of what the JSON object looks like: var dataSet1 = { meta: { "name": "Some text", "minimum": mini_ ...

HTML5 video player with secondary playlist

Looking for a videoplayer setup where there are two playlists, but only one can play at a time. When choosing a video from the first list initially, nothing happens. However, after selecting a video from the second list, the first list starts working. HTM ...

Error: The MUI Popper Component constantly closes when re-rendering due to props issue

I have been exploring how to structure a component incorporating MUI's Popover component, especially when dealing with dynamic props being passed to a controlled Slider component inside the Popover as well as the anchor element being updated dynamical ...

Having trouble setting the CSS width to 100%

Is there a way to assert the CSS width of an element in NightwatchJS to be 100% without hard-coding the value? Currently, when I attempt to do so, it fails and reports that the width is 196px. The specific error message is as follows: Testing if element ...

You need a function property for the child component to be updated

I recently encountered an unusual issue with my React components that has left me puzzled. Here is a condensed version of the app: class Child extends React.Component { componentDidUpdate(prev) { if (!prev.isActive && this.props.isActive) ...

The data retrieved from the web API is not undergoing the necessary conversion process

I am facing an issue with a web API call where the property checkNumber is defined as a double on the API side, but I need it to be treated as a string in my TypeScript model. Despite having the property defined as a string in my model, it is being receive ...

Attempting to showcase the text within an <a> element on a <canvas> element while ensuring there are no noticeable visual distinctions

Imagine having this snippet of code on a webpage: elit ac <a href="http://www.ducksanddos/bh.php" id='link'>Hello world!</a> nunc Now, picture wanting to replace the <a> tag with a <canvas> element that displays the same ...