Canvas希腊语谷歌字体无法正确呈现

时间:2015-02-11 18:56:32

标签: javascript google-chrome canvas fonts

我认为这是一个错误,但如果你们中的任何人知道任何解决方法,请告诉我。

首先,字体加载了101%。

  1. 我同步加载Google字体

  2. 我检查间隔以确保加载字体。

  3. 我通过使用canvas成功将字符串转换为图像(使用以下函数)(何时 我用英文字符)

  4. 渲染几个英文字符后,我尝试渲染一个希腊语 单词但帆布后退到浏览器默认字体。

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

  6. Bellow是在给定字符串的左上角创建带状标签背景图像的功能(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;
    
    };
    

1 个答案:

答案 0 :(得分:0)

经过一些测试,试验和错误以及许多小时的阅读......

我发现当你想在画布中使用它时,如果下载了字体并不重要。在我做任何其他事情之前对我有用的任何检查都是创建n * 2 div元素(n加载的字体数)并将它们放在view-port之外。 n * 2因为在某些我添加了font-weight:bold

底线是您希望在画布中使用的确切字体必须是:

  1. 预装
  2. 使用所有语言的innerHTML文本创建一个虚拟dom元素 变种(在我的情况下拉丁语和希腊语)。
  3. 保持在中间,您必须为字体的粗体变体创建额外的元素。

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

    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;
    
    };
    

    如果其他人在Chrome上遇到同样的问题,这对我有用。

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