2015-02-11 73 views
0

我认为这是一个错误,但如果你有任何人知道任何工作,请让我知道。帆布希腊谷歌字体不能正确渲染

首先,字体加载101%。

  1. 我加载谷歌字体同步

  2. 我与间隔检查,以确保该字体被加载。

  3. 我用帆布成功将字符串转换成图像(以下功能)(当 我用英文字符)

  4. 呈现几个英文字符后,我尝试呈现一个希腊 字但是画布会回退到浏览器的默认字体。

  5. Firefox根本没有任何问题,它的效果很好。 Chrome的问题是 。

娄是,从给定的字符串创建在左上角的带状标签背景图像的功能(PS:正在与其他的imageData稍后合并此函数返回的imageData):

ImageProcessor.prototype.createLabelImageData = function (str, size, font, color, backgroundColor, shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur, width, height) { 

    this.canvas.width = width || this.settings.width; 
    this.canvas.height = height || this.settings.height; 
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); 

    this.ctx.font = "Bold " + (size || 64) + "px " + (font || "Arial"); 
    this.ctx.textAlign = "center"; 
    this.ctx.textBaseline = "middle"; 

    var labelHeight = (size || 64) + ((size || 64)/4); 
    var labelTop = this.canvas.height/2 - labelHeight/2; 
    var labelWidth = this.canvas.width; 

    var strLen = this.ctx.measureText(str + " ").width; 
    var side = Math.sqrt((strLen * strLen)/2); 
    var distance = Math.sqrt((side * side) - ((strLen/2) * (strLen/2))); 

    this.ctx.save(); 
    this.ctx.rotate(-Math.PI/4); 
    this.ctx.translate(-this.canvas.width/2, -this.canvas.height/2 + distance); 

    this.ctx.fillStyle = (backgroundColor || '#f00'); 
    this.ctx.beginPath(); 
    this.ctx.moveTo(0, labelTop); 
    this.ctx.lineTo(labelWidth, labelTop); 
    this.ctx.lineTo(labelWidth, labelTop + labelHeight); 
    this.ctx.lineTo(0, labelTop + labelHeight); 
    this.ctx.closePath(); 
    this.ctx.fill(); 

    if (shadowColor) { 

     this.ctx.shadowColor = shadowColor; 
     this.ctx.shadowOffsetX = (shadowOffsetX || 0); 
     this.ctx.shadowOffsetY = (shadowOffsetY || 0); 
     this.ctx.shadowBlur = (shadowBlur || size || 64); 

    } 

    this.ctx.fillStyle = (color || "#fff"); 
    this.ctx.fillText(str, this.canvas.width/2, this.canvas.height/2); 
    this.ctx.restore(); 

    var imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height); 

    this.canvas.width = this.settings.width; 
    this.canvas.height = this.settings.height; 

    return imageData; 

}; 

回答

0

后好了一些测试,试验和错误和许多许多小时的阅读...

我发现,如果当你想在画布上使用的字体已经被下载了也没关系。在做任何事之前什么对我有效,并且任何检查都会创建n * 2个div元素(n个加载的字体数)并将它们放置在视图端口之外。 n * 2因为在一些我加入font-weight:bold

底线是,你想在画布上使用完全相同的字体必须是:

  1. 预装
  2. 建立在我的案件与所有语言 变化innerHTML的文本虚拟DOM元素(拉丁语&希腊)。

保持在中间,你必须为字体的粗体变化创建额外的元素。

这是我目前使用的预加载字体的代码,并确保它们在画布中可用。

Vise.prototype.initializeFonts = function (settings, globalCallback) { 



    var that = this; // reference to parent class 



    /******************************************** 
    ******************************************** 
    ** 
    ** 
    **  Default settings 
    ** 
    ** 
    ******************************************** 
    ********************************************/ 



    var defaults = { 
     interval: 100, 
     timeout: 10000, 
     families: [ 
      'Open+Sans+Condensed:300,300italic,700:latin,greek', 
      'Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800:latin,greek', 
      'Roboto+Condensed:300italic,400italic,700italic,400,700,300:latin,greek', 
      'Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic:latin,greek' 
     ] 
    }; 

    // initialization 

    this.fonts = new Fonts($.extend(true, defaults, settings)); 
    this.fonts.onload = globalCallback; 
    this.fonts.load(); 

}; 



/******************************************** 
******************************************** 
** 
** 
**  Fonts class 
** 
** 
******************************************** 
********************************************/ 



function Fonts(settings) { 

    this.settings = settings; 
    this.success = []; 
    this.fail = []; 
    this.interval = null; 
    this.elapsedTime = this.settings.interval; 
    this.fontDetective = new Detector(); 

} 

Fonts.prototype.load = function() { 

    WebFont.load({ 
     google: { 
      families: this.settings.families 
     } 
    }); 

    for (var i in this.settings.families) { 

     var el, elBold; 
     var familyStr = this.settings.families[ i ]; 
     var family = familyStr.split(':')[ 0 ].replace(/[+]/gi, ' '); 

     el = document.createElement("div"); 
     el.innerHTML = "Font loader Φόρτωμα γραμματοσειράς"; 
     el.style.fontFamily = family; 
     el.style.color = "#f00"; 
     el.style.position = "fixed"; 
     el.style.zIndex = 9999; 
     el.style.left = "9999px"; 
     document.body.appendChild(el); 

     elBold = document.createElement("div"); 
     elBold.innerHTML = "Font loader Φόρτωμα γραμματοσειράς"; 
     elBold.style.fontFamily = family; 
     elBold.style.fontWeight = "bold"; 
     elBold.style.color = "#f00"; 
     elBold.style.position = "fixed"; 
     elBold.style.zIndex = 9999; 
     elBold.style.left = "9999px"; 
     document.body.appendChild(elBold); 

    } 

    this.interval = setInterval(this.areLoaded.bind(this), this.settings.interval); 

}; 

Fonts.prototype.areLoaded = function() { 

    for (var i in this.settings.families) { 

     var familyStr = this.settings.families[ i ]; 
     var family = familyStr.split(':')[ 0 ].replace(/[+]/gi, ' '); 
     var successIdx, failIdx; 

     if (this.fontDetective.detect(family)) { 

      successIdx = this.success.indexOf(family); 
      failIdx = this.fail.indexOf(family); 

      if (successIdx === -1) { 
       this.success.push(family); 
       console.log("[" + family + "] was successfully loaded."); 
      } 

      if (failIdx > -1) { 
       this.fail.splice(failIdx, 1); 
      } 

     } else { 

      successIdx = this.success.indexOf(family); 
      failIdx = this.fail.indexOf(family); 

      if (successIdx > -1) { 
       this.success.splice(successIdx, 1); 
      } 

      if (failIdx === -1) { 
       this.fail.push(family); 
      } 

     } 

    } 

    if (this.elapsedTime >= this.settings.timeout) { 

     clearInterval(this.interval); 

     var err = new Error("Unable to load fonts: " + this.fail.toString()); 

     this.onload(err, null); 

     return; 
    } 

    if (this.success.length === this.settings.families.length) { 

     clearInterval(this.interval); 

     this.onload(null, null); 

     return; 
    } 

    this.elapsedTime += this.settings.interval; 

}; 

这是什么为我工作,以防别人在铬上遇到同样的问题。

PS:看看我在我的代码中使用的fontdetect.js