Canvas第一次不显示文本

时间:2018-02-28 16:08:47

标签: jquery firefox canvas fonts textbox

嗨我在画布上遇到了一些问题。 我有几个输入类型文本,对于每个文本,我需要创建带有文本的画布。当输入具有默认文本时,第一次在画布上不显示文本。我需要刷新才能看到firefox中的文本(以及在chrome隐身模式中应用字体的文本)。 我尝试做我在此处找到的解决方案:Drawing image on canvas in firefox on first load or reload with ctrl+f5 does not work或此处:Firefox won't draw to canvas on first visit但我无法让它们发挥作用。 对我有什么想法吗?感谢

这是我的简化代码:

(function( $ ) {
'use strict';

$(document).ready(function () {

    if(typeof(pgc)!='undefined'){
        somefunction(); //call this first because canvas need #preview width and height.
        setTimeout(create_pgc_text_container, 200, "non ajax");
    }


    function create_pgc_text_container(mode){
        console.log(mode);
        $('[id$="-field"]').each(function ()
        {
            var id=$(this).attr('id');
            var field_settings=pgc.text_settings[id];
            var field_datas=$.parseJSON(field_settings);
            var angle="rotate("+field_datas.angle+"deg)";
            $("#text_panel").append('<canvas id="'+field_datas.container+'" class="text_field jtextfill" style="font-size:'+field_datas.size+'px;top:'+field_datas.top+'%;transform:'+angle+';left:'+field_datas.left+'%;"><span></span></div>');

            var text = $(this).val();
            var current_field_id = $(this).attr('id');
            var current_color = $('#'+current_field_id).parent('.textfield-box').parent('.pgc-single-option-wrap.textfield').find('.pgc-textfield .pgc-textfield-color [data-field]').data('color');
            var current_font = $('#'+current_field_id).parent('.textfield-box').parent('.pgc-single-option-wrap.textfield').find('.pgc-textfield .pgc-textfield-font .font-selector[data-field]').val();
            var current_font_link = $('#'+current_field_id).parent('.textfield-box').parent('.pgc-single-option-wrap.textfield').find('.pgc-textfield .pgc-textfield-font .font-selector option:first').data('font');

            var image = new Image;
            image.src = current_font_link;
            $.when(current_font_link.load)
            .done(function () {
                image.onerror = function() {
                    console.log(current_font_link);
                    add_text_on_preview(text,current_field_id, current_font, current_color);       
                };
            });

            add_text_on_preview(text,current_field_id, current_font, current_color);
            // call again because some troubles in firefox loading first time.

            somefunction();

        });          
    }

    function add_text_on_preview(text, field_id, font, color){
        font = font || '';
        color = color || '';
        var field_settings = pgc.text_settings[field_id];
        var field_datas = $.parseJSON(field_settings);
        //console.log(field_datas.default_font);

        var mycanvas = $('#'+field_datas.container);
        mycanvas[0].width = $('#preview').width();
        mycanvas[0].height = $('#preview').height();

        var ctx = mycanvas[0].getContext('2d');

        var fontfamily = function() {
            var field_font;
            if (font == '') {
                if ( field_datas.default_font !== null ) {
                    field_font = field_datas.default_font;
                } else {
                    field_font = ' sans-serif';
                }
            }
            else
                field_font = font;

            if ( field_font.indexOf("://") != -1 ) {
                //console.log('found');
                fontUrlArray = field_font.split("=");
                if ( fontUrlArray.length >= 1 ) {
                    return fontUrlArray[1].split('+').join(' ');
                }
            }
            else {
                //console.log('not found', field_datas.font);
                return field_font;
            }

        }();

        ctx.clearRect(0, 0, mycanvas[0].width, mycanvas[0].height);

        field_datas.size = ( field_datas.size !== null && ( field_datas.size !== undefined && ( field_datas.size !== '' ) ) ) ? field_datas.size : 12 ; 
        //ctx.font = field_datas.size + 'px ' + font;
        ctx.font = field_datas.size + 'px ' + fontfamily;
        //console.log(ctx.font);

        if (color == '') 
            ctx.fillStyle = field_datas.default_color;
        else
            ctx.fillStyle = color;

        ctx.textBaseline = 'middle';
        ctx.textAlign = field_datas.text_align; 

        var positionTopText = ($('#preview').height() * field_datas.top)/100;
        var positionLeftText = ($('#preview').width() * field_datas.left)/100;
        //console.log(positionLeftText, positionTopText);

        ctx.fillText(text, positionLeftText, positionTopText);
    }


});

})( jQuery );

2 个答案:

答案 0 :(得分:1)

最后,我使用webfont.js和一些jquery promise。但是我被迫检查了一次以上所有的dom元素(测试)是否已加载。在下面的waitForEl函数中,我找到了here

     var waitForEl = function(selector, callback) {
      if (jQuery(selector).length) {
        callback();
      } else {
        setTimeout(function() {
          waitForEl(selector, callback);
        }, 100);
      }
    };

    WebFont.load({
        custom: {
            families: customFonts
        },
        google: {
            families: googleFonts
        },
        active: function() {
            console.log('webfonts loaded');
            waitForEl(inputs, function() {
              // here add my text element to canvas
            });
        },
    });

答案 1 :(得分:0)

我以前遇到过这个问题。使用外部字体的情况与使用图像时的情况相同,您需要在加载之前调用它。我在某个地方看到了这种骇人听闻的解决方案,并且对我有用(仍然试图查找源,以便可以在此处链接它)。

执行以下操作:

HTML: <p id="loadMe">Must include Text</p>

(将上面的标签放在<script><canvas>之前)

CSS:

@font-face {
  /*Define the font here*/
}

#loadMe {
  font-family: [Insert whatever it is];
}

如果先尝试将字体加载到画布上,则可以尝试如何隐藏加载器元素!您可能需要在js文件中使用style.fontFamily,以确保它不会从同一位置重新加载字体。