2

I'm trying to draw text onto a flag using a simple script. It works fine except for the Font not being loaded.

I've tried to load the font locally and from the web, but both don't work on my server.

However the code runs fine on w3 schools tryit editor

I think it has to do with the font not being loaded correctly or too late. What is the best way to make sure the font is loaded correctly?

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin">
<style>body { font-family: Ubuntu, sans-serif; }</style>
</head>
<body>

<canvas style="border-radius: 100px;" id="myCanvas" width="200" height="200">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}

var size = 200
var textSize=size * 0.55;
var countryCode = "nl";
var text = "123";

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var img = new Image;
img.onload = function(){
  ctx.drawImage(img,-1,-1,size,size); // removes the 1px border the flags sometimes have
  ctx.font = textSize+"px Ubuntu";
  ctx.textAlign="center";
  ctx.fillStyle = "#260C4D";
  ctx.fillText(text,size/2,size/2 + textSize / 2.85);
};
img.src = "http://www.geonames.org/flags/x/"+countryCode+".gif";
</script>

</body>
</html>
p.streef
  • 3,652
  • 3
  • 26
  • 50
  • what makes you think the font is already available when your canvas JS code kicks in? I don't see any code that checks to make sure the font is even done downloading/parsing/attaching to the graphics context...? – Mike 'Pomax' Kamermans Jun 06 '16 at 20:33

1 Answers1

1

I'm really tempted to vote to close as duplicate to this Q/A, but since you're in a particular case, I'll still post this answer, which may not be the best.

You are loading your font with a <link> element, so one way is to use its onload event handler. The problem with this approach is that the font may be cached, and the load event may have fired before it reaches your script declarations.

So you could use the href +'&'+ new Date().getTime() trick to make a new request to the server, or you can remove the <link> from the DOM and reappend it. This way, its load event should fire again even if the cached version is used. (Note that I only tested it on latest FF and Chrome, so it may not work in other browsers).

var link = document.querySelector('link');
link.onload = function() {
  log.textContent = 'loading image...';
  var size = 200
  var textSize = size * 0.55;
  var countryCode = "nl";
  var text = "123";

  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");

  var img = new Image;
  img.onload = function() {
    log.textContent='';
    ctx.drawImage(img, -1, -1, size, size); // removes the 1px border the flags sometimes have
    ctx.font = textSize + "px Ubuntu";
    ctx.textAlign = "center";
    ctx.fillStyle = "#260C4D";
    ctx.fillText(text, size / 2, size / 2 + textSize / 2.85);
  };
  img.src = "http://lorempixel.com/200/200";
}
// in case it's in the cache, it seems we have to remove it from the DOM and reinsert it
link.parentNode.removeChild(link);
document.head.appendChild(link)
body {
  font-family: Ubuntu, sans-serif;
}
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin">

<p id="log">loading font..</p>
<canvas style="border-radius: 100px;" id="myCanvas" width="200" height="200"></canvas>
Community
  • 1
  • 1
Kaiido
  • 123,334
  • 13
  • 219
  • 285