Wait for the canvas to fully load before locating the base64 data in HTML5

Wait until the full canvas is loaded before finding the base64 of that canvas, rather than relying on a fixed time interval.

function make_base(bg_img, width, height)
{
return new Promise(function(resolve, reject) {
  base_image = new Image();
  base_image.src = bg_img;
  base_image.onload = function(){
  ctx.drawImage(base_image, 0, 0, width, height);
  resolve()
  }
  })
}

function loadCanvas(width, height) {
    canvas = document.getElementById('canvas');
    canvas.id = "canvas";
    canvas.width = width;
    canvas.height = height;
    ctx = canvas.getContext("2d");
    canvas.style.zIndex   = 8;
    setTimeout(function() {
    base64 = canvas.toDataURL("image/jpeg",1);
    console.log(base64);
}, 3500);
}

function fillText(name, x_name, y_name, name_color, name_font) {
ctx.fillStyle = name_color;
ctx.font = name_font;
ctx.fillText(name, x_name, y_name);
}

Sometimes there is a delay in loading the canvas content. Setting a fixed 3.5 second timer for the base64 URL generation can result in getting a blank base64 if the canvas is not fully loaded in time.

function work() {
loadCanvas(x,y)
make_base(xxxxx).then(function () {
fillText(abcd)
})
}

Is there a way to ensure that the base64 is generated only after the canvas is fully loaded?

Answer №1

To enhance the efficiency of your code, consider moving the export functionality to a separate function and invoke it at the conclusion of your Promise chain:

var canvas, ctx;

work()
.then(function (url) {
  var img = new Image();
  img.src = url;
  document.body.appendChild(img);
}).catch(console.error);


function export_canvas() {
  base64 = canvas.toDataURL("image/jpeg", 1);
  console.log(base64);
  return base64;
}

function make_base(bg_img, width, height) {
  return new Promise(function (resolve, reject) {
    base_image = new Image();
    base_image.crossOrigin = "anonymous";
    base_image.src = bg_img;
    base_image.onload = function () {
      ctx.drawImage(base_image, 0, 0, width, height);
      resolve();
    }
  });
}

function setupCanvas(width, height) {
  canvas = document.getElementById("canvas");
  canvas.id = "canvas";
  canvas.width = width;
  canvas.height = height;
  ctx = canvas.getContext("2d");
  canvas.style.zIndex = 8;
}

function fillText(name, x_name, y_name, name_color, name_font) {
  ctx.fillStyle = name_color;
  ctx.font = name_font;
  ctx.fillText(name, x_name, y_name);
}

function work() {
  setupCanvas(80, 40);
  return make_base("https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png", 40, 40)
  .then(function () {
    fillText("abcd", 40, 10, "red");
    // ready to export
    return export_canvas();
  });
}
<canvas id="canvas">

Answer №2

I am uncertain about the situation, but there is a possibility that this could serve as a resolution to your issue.

When receiving the base64 string, you mentioned that it may sometimes be empty. In that case, store that string separately (in BASE64_NOT_READY) and utilize it to differentiate between being ready and not ready, similar to the following:

var interval = setInterval(function () {
  base64 = canvas.toDataURL("image/jpeg", 1);

  if (base64 !== BASE64_NOT_READY)
  {
    // The data is ready, stop the interval and proceed
    clearInterval(interval);
    console.log(base64);
  }
}, 100); // Check every 100 ms, actual time varies based on multiple factors

You must establish the specific string:

var BASE64_NOT_READY = "???";

This can be determined by implementing your own code. Replace the placeholder ??? with your solution, and you should be good to go!

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

The image wrapping feature within a div element will only function properly when there are more than one line of text present

I have come across a strange issue that I am struggling to solve. I have an image within a div with the float: left; attribute, but this styling only seems to work when the div has more than one line of text. When the div contains just one line, it ends ...

Is there a way to deactivate a button upon clicking and then substitute it with a new button that serves a different purpose in AngularJS?

Is there a way to deactivate a button once clicked and substitute it with another button that performs a different task using AngularJS? Here is the button in question: <button type="submit" class="btn btn-small btn-default" ng-disabled="isteam==0 || ...

I'm encountering difficulties utilizing ternary operators in TypeScript

I am struggling with ternary operators in TypeScript and need help understanding the issue. Please review the code below: const QuizQuestionContainer = ({ qa }: QuizQuestionContainerPropsType) => { const { question, option1, option2, option ...

What is the best way to create a dynamic URL linking to an external site in Angular 5?

When attempting to create a link like this: <a [href]="getUrl()">click me</a> getUrl() { return this.domSanitizer.bypassSecurityTrustUrl('http://sampleUrl.com'); } The link is not clickable. When hovering over the ...

I'm experiencing an issue where using .innerHTML works when viewing the file locally, but not when served from a web server. What could be causing this discrepancy?

Utilizing mootool's Request.JSON to fetch tweets from Twitter results in a strange issue for me. When I run the code locally as a file (file:// is in the URL), my formatted tweets appear on the webpage just fine. However, when I serve this from my loc ...

When using ng-repeat with Angular ui-bootstrap and tabs, the new tab will not be selected if there are no existing tabs present

To showcase the problem I'm facing, please refer to this link: http://codepen.io/pietrofxq/pen/ZLLJdr?editors=1010 Click on "remove tabs" and then on "add tab" The challenge at hand involves using a loop with ng-repeat to display tabs. At times, the ...

Styling text using CSS depending on the displayed text

Utilizing Awesome Tables (AT), I am extracting data from a Google Sheets document to display on a website. The HTML template in the sheets is used for formatting the data, specifically focusing on the table output with inline CSS styling. Since the templat ...

Bring in styles from the API within Angular

My goal is to retrieve styles from an API and dynamically render components based on those styles. import { Component } from '@angular/core'; import { StyleService } from "./style.service"; import { Style } from "./models/style"; @Component({ ...

Generating symbols that combine both images and text seamlessly

I am working with a circle image that I need to resize based on its placement. This image is intended to be a background for a character or two of text. Specifically, whenever the number 1 or 2 appears in a certain element, I want the circle to appear beh ...

Angular is able to select an element from a specified array

I'm currently struggling with using Angular to manipulate a TMDB API. I am having difficulty retrieving an item from an array. Can someone provide assistance? Here is the response that the array returns: { "id": 423108, "results ...

The text displayed on the image is experiencing fluctuations

I am experiencing an issue on my website where the post text fluctuates rapidly when the mouse hovers over the image. I have a site where I display the post text on mouseover of the image. Can someone please help me solve this problem? You can test it by ...

Adjust the top margin of content to account for the height of a fixed header

When dealing with a fixed header that has been removed from the HTML flow, it can be tricky to adjust the content below it. The challenge arises because the height of the header can vary based on screen size. How can we dynamically adjust the margin-top fo ...

Creating a repository of essential functions in AngularJSDiscover the steps to set up a

I am looking to create a set of reusable functions in AngularJS for CRUD operations that can be used across multiple entities in my project. I have already set up a factory using $resource for server communication, which looks like this: Model File: var ...

The functionality of JQuery TableSorter is not responsive when a user clicks on it

I seem to be running into an issue on my website where I can't get the JQuery TableSorter to work properly. When I attach it to a table for sorting, nothing happens when I click on the headers. The table remains static and unsortable. Here's a s ...

I am interested in using the split method to separate and then mapping an object in JavaScript

Need assistance on separating an array using the split method. The array contains objects with properties such as name, course1, course2, and course3. Only the courses with text in their content along with a plus sign should be separated into an array usin ...

Transfer the updated variable from a static JavaScript file to Next.js

I am facing a challenge with a conditional render in my component. I am unable to display the value of a variable. In one file, I have all my functions that I export in index.js import FunctionServices from "../services/functionServices" export ...

Bootswatch is causing the Bootstrap tooltip feature to malfunction

Could someone help me figure out why my tooltip isn't functioning properly? The HTML Code in Question: <div class="form-check"> <label class="form-check-label" > <input type="radio" class="form-check-input" name= ...

Using Python and Selenium, you can locate an element inside another element

I've got the xpath for an element: /html/body/div[1]/div/div[2]/div[3]/div/div/div/div[2]/div[1]/div[2]/div[6]/div/div/div/div[1] Inside that div, there's another element: /html/body/div[1]/div/div[2]/div[3]/div/div/div/div[2]/div[1]/div[2]/div[ ...

Dealing with Uncaught Type Errors in the Fixed Data Table

I am attempting to implement a fixed data table using the following code snippet. var MyCompi = React.createClass({ getInitialState: function() { return { rows : [ {"id":1,"first_name":"William","last_name":"Elliott","email":"<a ...

How can I make the top two divs stay fixed as I scroll down, and then reset back to their initial position when scrolled

Hey there, I'm looking to have a div stay fixed after scrolling within its parent div. <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12"> <div class="fw ofndr-box"> <div class="ofndr-box-half add-here"> <a href="#! ...