Html 将图形文本添加到<;帆布>;第一次使用@font-face时不起作用

Html 将图形文本添加到<;帆布>;第一次使用@font-face时不起作用,html,canvas,font-face,Html,Canvas,Font Face,当我在画布中使用通过@font-face加载的字体绘制文本时,文本无法正确显示。它根本不显示(在Chrome 13和Firefox 5中),或者字体错误(Opera 11)。这种类型的意外行为仅发生在第一个具有该字体的图形上。之后一切都很好 这是标准行为还是什么 多谢各位 PS:下面是测试用例的源代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &

当我在画布中使用通过@font-face加载的字体绘制文本时,文本无法正确显示。它根本不显示(在Chrome 13和Firefox 5中),或者字体错误(Opera 11)。这种类型的意外行为仅发生在第一个具有该字体的图形上。之后一切都很好

这是标准行为还是什么

多谢各位

PS:下面是测试用例的源代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>@font-face and &lt;canvas&gt;</title>
        <style id="css">
@font-face {
    font-family: 'Press Start 2P';
    src: url('fonts/PressStart2P.ttf');
}
        </style>
        <style>
canvas, pre {
    border: 1px solid black;
    padding: 0 1em;
}
        </style>
    </head>
    <body>
        <h1>@font-face and &lt;canvas&gt;</h1>
        <p>
            Description: click the button several times, and you will see the problem.
            The first line won't show at all, or with a wrong typeface even if it does.
            <strong>If you have visited this page before, you may have to refresh (or reload) it.</strong>
        </p>
        <p>
            <button id="draw">#draw</button>
        </p>
        <p>
            <canvas width="250" height="250">
                Your browser does not support the CANVAS element.
                Try the latest Firefox, Google Chrome, Safari or Opera.
            </canvas>
        </p>
        <h2>@font-face</h2>
        <pre id="view-css"></pre>
        <h2>Script</h2>
        <pre id="view-script"></pre>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script id="script">
var x = 30,
    y = 10;

$('#draw').click(function () {
    var canvas = $('canvas')[0],
        ctx = canvas.getContext('2d');
    ctx.font = '12px "Press Start 2P"';
    ctx.fillStyle = '#000';
    ctx.fillText('Hello, world!', x, y += 20);
    ctx.fillRect(x - 20, y - 10, 10, 10);
});
        </script>
        <script>
$('#view-css').text($('#css').text());
$('#view-script').text($('#script').text());
        </script>
    </body>
</html>

@字体和画布
@字体{
字体系列:“按开始2P”;
src:url('font/PressStart2P.ttf');
}
帆布,预{
边框:1px纯黑;
填充:0.1em;
}
@字体和画布

描述:单击按钮数次,您将看到问题。
第一行根本不会显示,即使显示了,也不会显示错误的字体。
如果您以前访问过此页面,您可能需要刷新(或重新加载)它。

#画

您的浏览器不支持画布元素。 试试最新的Firefox、Google Chrome、Safari或Opera。

@字体 剧本 var x=30, y=10; $('#draw')。单击(函数(){ var canvas=$('canvas')[0], ctx=canvas.getContext('2d'); ctx.font='12px“按开始2P'; ctx.fillStyle='#000'; ctx.fillText('Hello,world!',x,y+=20); ctx.fillRect(x-20,y-10,10,10); }); $('#查看css').text($('#css').text()); $('#查看脚本').text($('#脚本').text());
调用
fillText
方法时,必须在画布上绘制并立即返回。但是,浏览器尚未从网络加载字体,这是一项后台任务。因此,它必须回到可用的字体

如果要确保字体可用,请在页面上预装一些其他元素,例如:

<div style="font-family: PressStart;">.</div>

我最近玩它时碰到了这个问题

通过直接在CSS中将字体系列添加到画布中来解决此问题,因此您只需添加


canvas{font-family:PressStart;}

问题的关键在于您试图使用该字体,但浏览器尚未加载该字体,甚至可能尚未请求该字体。你需要的是加载字体并在加载后给你一个回调的东西;一旦收到回调,您就知道可以使用字体

看看谷歌的;它似乎是一个“自定义”提供程序,加载后的
活动
回调将使其工作

我以前从未使用过它,但通过快速扫描文档,您需要制作一个css文件
font/pressstart2p.css
,如下所示:

@font-face {
  font-family: 'Press Start 2P';
  font-style: normal;
  font-weight: normal;
  src: local('Press Start 2P'), url('http://lemon-factory.net/reproduce/fonts/Press Start 2P.ttf') format('ttf');
}
然后添加以下JS:

  WebFontConfig = {
    custom: { families: ['Press Start 2P'],
              urls: [ 'http://lemon-factory.net/reproduce/fonts/pressstart2p.css']},
    active: function() {
      /* code to execute once all font families are loaded */
      console.log(" I sure hope my font is loaded now. ");
    }
  };
  (function() {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
        '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
  })();

首先,按照另一个答案中的建议使用Google的Web字体加载器,并将绘图代码添加到它提供的回调中,以指示字体已加载。然而,这并不是故事的结局。从这一点来看,它非常依赖于浏览器。大多数情况下,它都可以正常工作,但有时可能需要等待几百毫秒或在页面上的其他地方使用字体。我尝试了不同的选项,afaik总是有效的一种方法是在画布中快速绘制一些测试消息,其中包含您将要使用的字体系列和字体大小组合。你可以用和背景相同的颜色来做,这样它们就看不见了,而且会很快发生。此后,字体在我和所有浏览器中都适用。

使用
onerror
事件并将其绑定到
图像
元素

演示:在最新的Chrome上工作

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'http://fonts.googleapis.com/css?family=Vast+Shadow';
document.getElementsByTagName('head')[0].appendChild(link);

// Trick from https://stackoverflow.com/questions/2635814/
var image = new Image();
image.src = link.href;
image.onerror = function() {
    ctx.font = '50px "Vast Shadow"';
    ctx.textBaseline = 'top';
    ctx.fillText('Hello!', 20, 10);
};

面临同样的问题。在阅读了“bobince”和其他评论之后,我使用以下javascript来解决这个问题:

$('body').append("<div id='loadfont' style='font-family: myfont;'>.</div>");
$('#loadfont').remove();
$('body')。追加(“.”);
$(“#加载字体”).remove();

我不确定这是否会对您有所帮助,但为了解决代码的问题,我只是在Javascript顶部创建了一个for循环,它运行了我想要加载的所有字体。然后,我运行一个函数来清除画布,并在画布上预加载我想要的项目。到目前为止,它工作得很好。这就是我的逻辑,我将我的代码发布在下面:

var fontLibrary = ["Acme","Aladin","Amarante","Belgrano","CantoraOne","Capriola","CevicheOne","Chango","ChelaOne","CherryCreamSoda",
"ConcertOne","Condiment","Damion","Devonshire","FugazOne","GermaniaOne","GorditasBold","GorditasRegular",
"KaushanScript","LeckerliOne","Lemon","LilitaOne","LuckiestGuy","Molle","MrDafoe","MrsSheppards",
"Norican","OriginalSurfer","OswaldBold","OswaldLight","OswaldRegular","Pacifico","Paprika","Playball",
"Quando","Ranchers","SansitaOne","SpicyRice","TitanOne","Yellowtail","Yesteryear"];

    for (var i=0; i < fontLibrary.length; i++) {
        context.fillText("Sample",250,50);
        context.font="34px " + fontLibrary[i];
    }

    changefontType();

    function changefontType() {
        selfonttype = $("#selfontype").val();
        inputtextgo1();
    }

    function inputtextgo1() {
        var y = 50;
        var lineHeight = 36;
        area1text = document.getElementById("bag1areatext").value;
        context.clearRect(0, 0, 500, 95)
        context.drawImage(section1backgroundimage, 0, 0);
        context.font="34px " + selfonttype;
        context.fillStyle = seltextcolor;
        context.fillText(area1text, 250, y);
    }
var fontLibrary=[“Acme”、“Aladin”、“Amarante”、“Belgrano”、“CantoraOne”、“Capriola”、“CevicheOne”、“Chango”、“ChelaOne”、“CherryCreamSoda”,
“协奏曲”、“调味品”、“达米翁”、“德文郡”、“富加松”、“日耳曼奥涅”、“戈尔迪塔斯波尔德”、“戈尔迪塔斯勒姆”,
“KaushanScript”,“LeckerliOne”,“Lemon”,“LilitaOne”,“LuckiestGuy”,“Molle”,“MrDafoe”,“MrsSheppards”,
“挪威人”、“原始冲浪者”、“奥斯瓦尔德堡人”、“奥斯瓦尔德莱特人”、“奥斯瓦尔德勒姆人”、“帕西菲科人”、“红辣椒”、“玩球”,
“全多”、“牧场主”、“三世通”、“蜘蛛花”、“泰坦通”、“黄尾”、“昨天”];
对于(变量i=0;i
我的答案是针对谷歌网页字体,而不是@font-face。我到处寻找解决画布上字体不显示问题的方法。我尝试了计时器、设置间隔、字体延迟库和各种技巧。什么都没用。(包括将字体系列放入画布或
<!-- you need to empty your browser cache and do a hard reload EVERYTIME to test this otherwise it will appear to working when, in fact, it isn't -->

<h1>Title Font</h1>

<p>Paragraph font...</p>
<canvas id="myCanvas" width="740" height="400"></canvas>
@import url(http://fonts.googleapis.com/css?family=Architects+Daughter);
 @import url(http://fonts.googleapis.com/css?family=Rock+Salt);
 canvas {
    font-family:'Rock Salt', 'Architects Daughter'
}
.wf-loading p {
    font-family: serif
}
.wf-inactive p {
    font-family: serif
}
.wf-active p {
    font-family:'Architects Daughter', serif;
    font-size: 24px;
    font-weight: bold;
}
.wf-loading h1 {
    font-family: serif;
    font-weight: 400;
    font-size: 42px
}
.wf-inactive h1 {
    font-family: serif;
    font-weight: 400;
    font-size: 42px
}
.wf-active h1 {
    font-family:'Rock Salt', serif;
    font-weight: 400;
    font-size: 42px;
}
// do the Google Font Loader stuff....
WebFontConfig = {
    google: {
        families: ['Architects Daughter', 'Rock Salt']
    }
};
(function () {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
        '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
})();

//play with the milliseconds delay to find the threshold - don't forget to empty your browser cache and do a hard reload!
setTimeout(WriteCanvasText, 0);

function WriteCanvasText() {
    // write some text to the canvas
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
    context.font = "normal" + " " + "normal" + " " + "bold" + " " + "42px" + " " + "Rock Salt";
    context.fillStyle = "#d50";
    context.fillText("Canvas Title", 5, 100);
    context.font = "normal" + " " + "normal" + " " + "bold" + " " + "24px" + " " + "Architects Daughter";
    context.fillText("Here is some text on the canvas...", 5, 180);
}
#preloadfont {
  font-family: YourFont;
  opacity:0;
  height:0;
  width:0;
  display:inline-block;
}
<body>
   <div id="preloadfont">.</div>
   <canvas id="yourcanvas"></canvas>
   ...
</body>
<script>
var c = document.getElementById('myCanvas');    
var ctx = c.getContext('2d');
setTimeout(function() {
    ctx.font = "24px 'Proxy6'"; // uninstalled @fontface font style 
    ctx.textBaseline = 'top';
    ctx.fillText('What!', 20, 10);      
}, 100); 
</script>
const myFont = new FontFace('My Font', 'url(https://myfont.woff2)');

myFont.load().then((font) => {
  document.fonts.add(font);

  console.log('Font loaded');
});
var myFont = new FontFace('My Font', 'url(https://myfont.woff2)');

myFont.load().then(function(font){

  // with canvas, if this is ommited won't work
  document.fonts.add(font);

  console.log('Font loaded');

});
var fontFaceSet = document.fonts;
if (fontFaceSet && fontFaceSet.addEventListener) {
    fontFaceSet.addEventListener('loadingdone', function () {
        // Redraw something

    });
} else {
    // no fallback is possible without this API as a font files download can be triggered
    // at any time when a new glyph is rendered on screen
}
.preloadFont {
    font-family: 'Audiowide', Impact, Charcoal, sans-serif, cursive;
    font-size: 0;
    position: absolute;
    visibility: hidden;
}
<body onload="init()">
  <div class="preloadFont">.</div>
  <canvas id="yourCanvas"></canvas>
</body>
function init() {
    myCanvas.draw();
}
const prepareFontLoad = (fontList) => Promise.all(fontList.map(font => document.fonts.load(font)))
    <link rel="preload" as="font" href="assets/fonts/Maki2/fontmaki2.css" rel="stylesheet" crossorigin="anonymous">