Closed cy920820 closed 4 months ago
To address the issue of SVG images not working on iOS, you can try the following steps:
SVGFile.js
: Ensure that the SVG is correctly parsed and processed. Add a check for iOS and handle the SVG differently if needed.// Inside SVGFile.js
onProcess: function () {
this.state = CONST.FILE_PROCESSING;
var text = this.xhrLoader.responseText;
var svg = [ text ];
var width = this.config.width;
var height = this.config.height;
var scale = this.config.scale;
// Check for iOS
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
resize: if (width && height || scale) {
var xml = null;
var parser = new DOMParser();
xml = parser.parseFromString(text, 'text/xml');
var svgXML = xml.getElementsByTagName('svg')[0];
var hasViewBox = svgXML.hasAttribute('viewBox');
var svgWidth = parseFloat(svgXML.getAttribute('width'));
var svgHeight = parseFloat(svgXML.getAttribute('height'));
if (!hasViewBox && svgWidth && svgHeight) {
svgXML.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight);
} else if (hasViewBox && !svgWidth && !svgHeight) {
var viewBox = svgXML.getAttribute('viewBox').split(/\s+|,/);
svgWidth = viewBox[2];
svgHeight = viewBox[3];
}
if (scale) {
if (svgWidth && svgHeight) {
width = svgWidth * scale;
height = svgHeight * scale;
} else {
break resize;
}
}
svgXML.setAttribute('width', width.toString() + 'px');
svgXML.setAttribute('height', height.toString() + 'px');
svg = [ (new XMLSerializer()).serializeToString(svgXML) ];
}
try {
var blob = new window.Blob(svg, { type: 'image/svg+xml;charset=utf-8' });
} catch (e) {
this.onProcessError();
return;
}
this.data = new Image();
this.data.crossOrigin = this.crossOrigin;
var _this = this;
var retry = false;
this.data.onload = function () {
if (!retry) {
File.revokeObjectURL(_this.data);
}
_this.onProcessComplete();
};
this.data.onerror = function () {
if (!retry) {
retry = true;
File.revokeObjectURL(_this.data);
_this.data.src = 'data:image/svg+xml,' + encodeURIComponent(svg.join(''));
} else {
_this.onProcessError();
}
};
if (isIOS) {
// Special handling for iOS
this.data.src = 'data:image/svg+xml,' + encodeURIComponent(svg.join(''));
} else {
File.createObjectURL(this.data, blob, 'image/svg+xml');
}
}
LoaderPlugin.js
: Ensure that the SVG file type is registered correctly.// Inside LoaderPlugin.js
FileTypesManager.register('svg', function (key, url, svgConfig, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new SVGFile(this, key[i]));
}
} else {
this.addFile(new SVGFile(this, key, url, svgConfig, xhrSettings));
}
return this;
});
TextureManager.js
: Ensure that the texture is added correctly.// Inside TextureManager.js
addImage: function (key, source, dataSource) {
var texture = null;
if (this.checkKey(key)) {
texture = this.create(key, source);
Parser.Image(texture, 0);
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
}
These changes should help in handling SVG images on iOS devices.
/src/loader/filetypes/SVGFile.js /src/loader/LoaderPlugin.js /src/textures/TextureManager.js /src/gameobjects/image/Image.js
It can (see image below) - but you shouldn't load SVGs via load.image
. Use load.svg
for this, or use bitmap images. iOS does something weird when loading SVGs as Image data, which for some reason often takes a while for them to decode. In short, don't do it the way you're doing it.
case: https://codepen.io/cy920820/pen/ExBYJZo