我使用下面的代码来渲染谷歌字体并更新画布:
/* on change of font load the preview as well as canvas */
$('#font').on('change', function () {
$('.font_preview').show();
var font_family = $(this).val();
$('.font_preview').css('font-family', font_family, 14);
$('.font_preview').html(font_family,'');
load_web_font([font_family],'.font_preview',font_family,1);
});
function load_web_font(font_family, preview_div,font_family_text,preview_text) {
var grep_font = jQuery.grep(font_family, function (n, i) {
return ( n );
});
if (grep_font.length > 0) {
var preview_text;
if (preview_div) {
preview_text = $(preview_div).text();
}
WebFont.load({
google: {
families: font_family
},
fontloading: function (familyName, fvd) {
if (preview_div) {
if(preview_text==1)
{
$(preview_div).text('font loading ... ');
}
}
},
fontactive: function (familyName, fvd) {
if (preview_div) {
if(preview_text==1)
{
$(preview_div).text(preview_text);
}
load_font_on_canvas(font_family_text);
}
},
timeout: 10000
});
}
}
//Load Font on Canvas
function load_font_on_canvas(font_style)
{
var font_style = font_style;
if(font_style=='')
{
alert('Please select a Font Style');
return false;
}
var tObj = canvas.getActiveObject();
//Check that text is selected
if(tObj==undefined)
{
alert('Please select a Text');
return false;
}
tObj.set({
fontFamily: font_style
});
canvas.renderAll();
}
现在,我将画布数据存储为DB中的json。因此,当用户尝试编辑该画布时,我将使用下面的代码渲染画布:
if(is_update==1) // Update then load the card
{
// parse the data into the canvas
canvas1.loadFromJSON(front_side_object);
// re-render the canvas
canvas1.renderAll();
canvas2.loadFromJSON(back_side_object);
canvas2.renderAll();
}
所以画布正在加载,但不是用户选择的字体。所以我试过下面的代码用google字体来更新画布,但它不能正常工作
//Grab each google fonts
var all_fonts = [];
$('#font option').each(function(){
var font_family = $(this).val();
//all_fonts += font_family + '|';
if(font_family!='')
{
all_fonts.push(font_family);
}
});
load_all_web_font(all_fonts);
function load_all_web_font(all_fonts)
{
var grep_font = jQuery.grep(all_fonts, function (n, i) {
return ( n );
});
WebFont.load({
google: {
families: all_fonts
},
fontloading: function (familyName, fvd) {
//Do Something
},
fontactive: function (familyName, fvd) {
//1st Try rerender canvas again after fonts is loaded
//Do SOmething
canvas1.loadFromJSON(front_side_object);
// re-render the canvas
canvas1.renderAll();
canvas2.loadFromJSON($model->back_side_object);
canvas2.renderAll();
//Get the text and rerender the canvas
canvas1.getObjects().filter(function(o) {
if (o.get('type') === 'text') {
console.log(o.get);
canvas1.renderAll();
}
});
canvas2.getObjects().filter(function(o) {
if (o.get('type') === 'text') {
canvas2.renderAll();
}
});
},
timeout: 10000
});
}
答案 0 :(得分:0)
我知道这是一个老问题,但我遇到了同样的问题。您需要做的是将 Text 的 dirty
属性设置为 true,然后调用 canvas.renderAll()
。
我使用的一个示例(在 TypeScript 中)是在加载 JSON 后调用我的函数 rerenderWhenAFontisLoaded
:
import FontFaceObserver from 'fontfaceobserver';
const myFonts = ['Pacifico', 'VT323', 'Quicksand'];
const rerenderWhenAFontIsLoaded = (): void => {
let timer: NodeJS.Timeout | null = null;
myFonts.forEach((font) => {
new FontFaceObserver(fontName)
.load()
.then(() => {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
const [fonts] = getObjectsOfTypes(canvas, [['textbox', 'i-text', 'text']]);
fonts.forEach((font) => {
font.dirty = true;
});
canvas.requestRenderAll();
}, 1000);
})
.catch(() => {
// dont care
});
});
};
/**
* An recursive function to return an array of objects as defined in the types argument.
* @param object Either an canvas or a group object
* @param types: like [['polygon'], [['i-text', 'textbox', 'text']]
* @returns array of fabric.Objects in the same order as you defined in the types argument.
*/
const getObjectsOfTypes = (object: fabric.Object | fabric.Canvas, types: string[][]): fabric.Object[][] => {
const result: fabric.Object[][] = [];
for (let i = 0; i < types.length; i++) {
result.push([]);
if (types[i].includes((object as fabric.Object).type!)) {
result[i].push(object as fabric.Object);
break;
}
}
// Check if we can call getObjects, then we either know it's the canvas or another group.
if (typeof (object as fabric.Group).getObjects === 'function') {
(object as fabric.Group | fabric.Canvas).getObjects().forEach((object) => {
const moreRelevantObjects = this.getObjectsOfType(object, types);
moreRelevantObjects.forEach((objects, i) => {
result[i].push(...objects);
});
});
}
return result;
};