Fabric js Текстовые символы искажены на iPhone и iPad
Мы используем Fabric js для вставки текста в канву, мы вставляем 2 текста, один из них - большой текст, который загружается правильно и имеет шрифт Open Sans. Другой - текст меньшего размера, в котором у нас проблемы, динамические шрифты загружаются из библиотеки шрифтов Google динамически. Вместо отображения символов он отображает знаки вопроса в полях. Мы пытались использовать шрифт Open Sans, но без изменений.
Для дальнейшего объяснения вы можете проверить следующую ссылку, я использовал следующий код, который создает проблему
_preloadText: function(index,value)
{
var fontSize = value.default;
var coords = this._getXYCoordinates(value.coordinates);
var fontFamily = this.options.fontFamily;
var options = $.extend({
fontFamily: fontFamily,
fontSize: fontSize,
useNative:true
},this._getOptions(coords.x,coords.y));
if('text' == value.type)
{
options.fontStyle = 'bold';
options.fontFamily = 'Open Sans';
var title = new fabric.Text(value.text,options);
this.canvasLayer2.add(title);
this.canvasLayer2.centerObjectH(title);
this.canvasLayer2.setActiveObject(title);
this.canvasLayer2.renderAll();
}else{
/*The below code is where the problem of fallback font is.*/
var slogan = new fabric.Text(value.text,options);
this.canvasLayer3.add(slogan);
this.canvasLayer3.centerObjectH(slogan);
this.canvasLayer3.setActiveObject(slogan);
this.canvasLayer3.renderAll();
}
}
Есть и другие, кто тоже сталкивался с этой проблемой. Вы можете проверить, открыв следующую кодовую ручку в iPhone или iPad https://codepen.io/kelvin-im/pen/xrRNEx/
Я также обнаружил, что эта проблема указана в учетной записи фабрики js github https://github.com/kangax/fabric.js/issues/4009
Но разработчик внезапно закрыл вопрос, не скрывая комментариев.
редактировать
Вот код загрузки шрифта, который вызывается первым, когда этот виджет jquery инициализируется.
_prepareFont: function(){
var that = this;
if(this.options.fontFamily !== null){
require(['https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js'],function(WebFont){
WebFont.load({
google: {
families: [that.options.fontFamily]
},
active: function() {
that._prepareCanvas();
that._prepareControls();
},
fontactive: function(familyName, fvd){
that.options.fontFamily = familyName;
}
});
});
}
}
В библиотеке WebFont мы загружаем шрифт, а при активном событии мы вызываем метод _prepareControls, который предварительно загружает текст в canvas. Если мы не получаем нужный шрифт из библиотеки Google WebFont, мы используем шрифт Open Sans, который уже добавлен на страницу.
Мы используем 2 экземпляра ткани. Текстовый класс, один загружается, другой нет.
1 ответ
Крутой разработчик, я, дважды попросил посмотреть код загрузки шрифта. Шрифты должны быть загружены браузером, прежде чем пытаться использовать их на холсте.
В противном случае вы получите запасной шрифт или мусор на экране.
Теперь я переместил кодовую ручку сюда, завернул заголовок за 2 секунды. Вы заметите, что на iphone/ipad или других медленных устройствах этих 2 секунд должно быть достаточно, чтобы сервер Google сначала выдал вам строку css, а затем второй запрос, который требуется браузеру, чтобы получить файл шрифта и загрузить canvas. это, в то время как другой текст мог бы появиться как мусор, не должен делать Головная линия.
$(document).ready(function() {
$('.browser-type').html(bowser.name + ' ' + bowser.version);
var canvas = new fabric.Canvas('c');
$('.fabric-type').html(fabric.version);
var headline = new fabric.IText('Headline', {
"originX": "center",
"originY": "center",
"left": 512,
"top": 117,
"width": 83.6,
"height": 56.5,
"fill": "#ffffff",
"stroke": null,
"strokeWidth": 0,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.8,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": "",
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"skewX": 0,
"skewY": 0,
"name": "Headline txt",
"locked": ["stroke"],
"perPixelTargetFind": false,
"fontSize": 165,
"fontWeight": "800",
"fontFamily": "Open Sans",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {
"0": {
"1": {},
"2": {},
"3": {},
"4": {},
"5": {},
"6": {},
"7": {}
}
}
});
var dateTime = new fabric.IText('Date | Time', {
"originX": "center",
"originY": "center",
"left": 512,
"top": 206,
"width": 170.31,
"height": 31.64,
"fill": "#ffffff",
"stroke": null,
"strokeWidth": 0,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.9,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": "",
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"skewX": 0,
"skewY": 0,
"name": "date/time",
"locked": ["stroke"],
"perPixelTargetFind": false,
"fontSize": 28,
"fontWeight": "400",
"fontFamily": "Open Sans",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {
"0": {
"1": {},
"2": {},
"3": {},
"4": {}
}
}
});
var vsText = new fabric.IText('vs.', {
"originX": "center",
"originY": "center",
"left": 512,
"top": 255,
"width": 83.6,
"height": 56.5,
"fill": "#ffffff",
"stroke": null,
"strokeWidth": 0,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.8,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": "",
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"skewX": 0,
"skewY": 0,
"name": "versus txt",
"locked": ["stroke"],
"perPixelTargetFind": false,
"fontSize": 50,
"fontWeight": "400",
"fontFamily": "RIVERHACK",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {
"0": {
"1": {},
"2": {},
"3": {}
}
}
});
var sideText = new fabric.IText('SIDEBAR', {
"originX": "center",
"originY": "center",
"left": 50,
"top": 30,
"width": 90.72,
"height": 36.21,
"fill": "#0c0c0c",
"stroke": null,
"strokeWidth": 0,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": "",
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"skewX": 0,
"skewY": 0,
"name": "sidebar txt",
"locked": ["stroke"],
"perPixelTargetFind": false,
"fontSize": 18,
"fontWeight": "400",
"fontFamily": "Open Sans",
"fontStyle": "",
"lineHeight": 0.78,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {
"0": {
"1": {},
"2": {},
"3": {},
"4": {},
"5": {},
"6": {},
"7": {},
"8": {}
},
"1": {
"0": {},
"1": {},
"2": {},
"3": {},
"4": {}
}
}
});
canvas.add(sideText);
canvas.add(dateTime);
canvas.add(vsText);
setTimeout(function() {
canvas.add(headline);
}, 2000);
});
@import
url(https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i,800,800i);
#c {
border: 1px solid #ccc;
background-color: #aaa;
box-shadow: 3px 3px 3px #999;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bowser/1.0.0/bowser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.13/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div>
<b>Browser:</b> <span class="browser-type"></span><br>
<b>Fabric JS:</b> <span class="fabric-type"></span>
<br><br>
<div>
<canvas id='c' width="1024" height="1024"></canvas>
</div>
</div>
В сафари: