add background image on html 5 canvas

Viewed 1185

I want to generate a image that can be shared, using HTML 5 canvas , but i'm getting problem to add images canvas:

here is my code:

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div id="the_text" style="display: none;width:100%;height:1000px;background-color:red;">
    CERTIFICATE OF ATTENDANCE

  </div>
  <button id="show_img_btn">Search</button>
  <div class=" center-screen" id="show_img_here" style="">

  </div>

</body>

<script async src="https://static.addtoany.com/menu/page.js"></script>

Javascript:

window.onload = function() {
  $("#show_img_btn").on("click", function() {
    var canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 500;
    var ctx = canvas.getContext('2d');

    var img1 = new Image();

    //drawing of the test image - img1
    img1.onload = function() {
      //draw background image
      ctx.drawImage(img1, 0, 0);
      //draw a box over the top
      ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
      ctx.fillRect(0, 0, 800, 500);

    };

    img1.src = 'http://cdn.playbuzz.com/cdn/503aeb8a-c1b8-4679-8ed3-da5e11643f29/8a940ebd-8630-4247-888e-c4c611f4f0e2.jpg';

    // rest of content

    ctx.fillStyle = '#c3d200';
    ctx.font = "45px panton";
    var text = $("#the_text").text();
    ctx.fillText(text, 10, 120);

    ctx.fillStyle = '#000000';
    ctx.font = "17px panton";
    var text = $("#the_text").text();
    ctx.fillText('Lorem ipsum dolor sit amet, consectetur:', 230, 280);

    ctx.fillStyle = '#000000';
    ctx.font = " bold 31px panton";
    var text = $("#the_text").text();
    ctx.fillText('Lorem ipsum dolor sit amet, consectetur', 180, 350);

    ctx.fillStyle = '#000000';
    ctx.font = " bold 31px panton";
    var text = $("#the_text").text();
    ctx.fillText('Lorem ipsum dolor sit amet, consectetur adipiscing', 80, 400);

    // create image
    var img = document.createElement("img");
    img.src = canvas.toDataURL();
    $("#show_img_here").append(img);
    //$("body").append(canvas);
  });
};

// share icons
var a2a_config = a2a_config || {};
a2a_config.overlays = a2a_config.overlays || [];
a2a_config.overlays.push({
  services: ['twitter', 'facebook', 'linkedin', 'email'],
  size: '50',
  style: 'horizontal',
  position: 'top center'
});

CSS:

body {
  background: white;
}



button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}


.center-screen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  min-height: 100vh;
}

I also tried something like this, but dosent work.

var background = new Image();
background.src = "http://cdn.playbuzz.com/cdn/503aeb8a-c1b8-4679-8ed3-da5e11643f29/8a940ebd-8630-4247-888e-c4c611f4f0e2.jpg";

background.onload = function(){
    ctx.drawImage(background,0,0);   
}

or draw a image using image source:

var img = document.getElementById("image");
    ctx.drawImage(img, 0, 0);


None of this worked.

Note: using tag on html would fix my problem of inserting images , but it will not going to recognize as image to be shared on social networks.

here is the Demo test link: FIDDLE DEMO

2 Answers

Render content after loading

You are rendering content (text) to the canvas and adding that content as an image before the background image has loaded.

Then the background image load event fires and you draw the background image over the content, but as you have already displayed the canvas content (as an image) thus the background image is never displayed.

Always use the Image.onload event

When ever you set an Image.src attribute use the load event to start any form of rendering involving that image.

Example

Example is taken from your posted code and cut down to show the basics. The background image is cross domain which taints the canvas thus example has the final output (as Image) commented out. Instead of an image it just adds the canvas when the render is complete.

The whole render process is in one function that is called when the background image has loaded.

I have removed jQuery as it is irrelevant to the problem and solution.

show_img_btn.addEventListener("click", function() {
    const canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 500;
    const ctx = canvas.getContext('2d');

    const bgImg = new Image();
    bgImg.src = 'http://cdn.playbuzz.com/cdn/503aeb8a-c1b8-4679-8ed3-da5e11643f29/8a940ebd-8630-4247-888e-c4c611f4f0e2.jpg';
    
    bgImg.addEventListener("load", () => drawContent(ctx, bgImg), {once: true});
    ctx.fillText("Loading image...", 50, 50);
    
});
function drawContent(ctx, bgImg) {
    ctx.drawImage(bgImg, 0, 0);
    ctx.fillStyle = "rgba(200, 0, 0, 0.5)";
    ctx.fillRect(0, 0, 800, 500);

    ctx.textAlign = "center";
    ctx.fillStyle = '#c3d200';
    ctx.font = "45px panton";
    ctx.fillText(the_text.textContent, ctx.canvas.width / 2, 120);

    /* Tainted canvas can not get pixel data on cross origin image (from cdn.playbuzz.com to stackoverflow.com)
    var img = document.createElement("img");
    img.src = ctx.canvas.toDataURL();
    img.addEventListener("load", () => {
          show_img_here.appendChild(img);
    }, {once: true});
     */

    show_img_here.appendChild(ctx.canvas);

};
body {
  background: white;
}
button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}
<div id="the_text" style="display: none;width:100%;height:1000px;background-color:red;">CERTIFICATE OF ATTENDANCE</div>
<button id="show_img_btn">Load & create image</button>
<div class=" center-screen" id="show_img_here" style=""></div>

i found out that converting the png or jpg file to base64 solved my problem:

  1. by converting to base64 is now possible to transform the canvas to png or jpg;
  2. the social network icons plug-in is now recognizing the picture as image;

enter image description here

Related