我使用Two.js,我想允许用户导入svg文件并在我的场景中显示它。
Two.interpret()可以获取其中包含SVG数据的任何标签dom,因此我创建了此函数来模拟文件中的标记:
this.m_Two.interpretFromFile = function (two, fname) {
//Create an object and load an svg from 'fname'
var object = document.createElement("object");
//Set the id to the filename without path or extension
object.id = fname;
object.id = object.id.replace(/\\/g, '/');
object.id = object.id.substring(object.id.lastIndexOf('/')+1, object.id.lastIndexOf('.'));
console.log("Importing " + object.id);
object.data = fname; //HTML takes care of the rest
object.type = "image/svg+xml";
object.width = 64; //Import from file maybe?
object.height = 64;
object.style = "visibility:hidden;position:absolute;left:0px;top:0px;";
document.body.appendChild(object); //Add it to the body (invis) that way it loads
//When it loads, finish up
object.onload = function () {
if (!object.contentDocument || object.contentDocument.getElementsByTagName("svg").length < 1) return;
var svgObj = object.contentDocument.getElementsByTagName('svg')[0];
var ret = two.interpret(svgObj);
document.body.removeChild(object); //Remove it. Use path.clone to duplicate stuff..
return ret; //Return our new svg path
}
};
此函数采用Two实例和文件url,并返回two.path。
使用控制台时,这一切都很好用 twoInstance.interpretFromFile(twoInstance,&#34; images / Test.svg&#34;);
但是,我在本地运行这些文件进行测试,我当然不希望任何人进入他们的浏览器控制台并使用该功能,已经知道该文件的确切路径,并且还知道键入&#34; file://&#34;在那条路之前...... Yeesh
document.getElementById("dWorkSpace").ondrop = function(e) {
e.preventDefault(); //Default event loads the file itself.. KILL IT WITH FIRE.
if (!e.dataTransfer || !e.dataTransfer.items.length > 0 || !e.dataTransfer.files[0]) return;
var file = e.dataTransfer.files[0];
twoInstance.interpretFromFile(twoInstance, "file://" + file.name);
}
&#39; file.name&#39;只提供文件,而不是路径(是的,我知道这在浏览器中是安全的。我已经查看了所有其他有关此问题的问题......)
现在,我可以使用FileReader来读取svg文件本身,但是如何将这些数据转换为标签呢?我在某种程度上需要这种格式:
<object data="Test.svg" type="image/svg+xml"></object>
因为Two.js似乎不喜欢&#39; svg&#39;标签..只是&#39;对象&#39;标签..
我很抱歉这个长期存在的问题......正如你所看到的,我在这个兔子洞的深处。我试图只使用相关的代码,但说实话,整个事情都非常庞大,我讨厌发布它。
答案 0 :(得分:2)
这是我上传svg图像并附加到div的方法,使用atob将base64字符串转换为svg字符串:var svg = atob(event.target.result.replace(/data:image\/svg\+xml;base64,/, ''));
我在有角度的应用中使用它。我与谁分享关注点。
handleFileInput(file: FileList) {
this.fileToUpload = file.item(0);
var xlinkNS = "http://www.w3.org/1999/xlink";
//Show image preview
let reader = new FileReader();
reader.onload = (event: any) => {
var svg = atob(event.target.result.replace(/data:image\/svg\+xml;base64,/, ''));
console.log(svg);
var element = document.createElement("div");
element.id = "svg";
document.getElementsByClassName('svg-container')[0].innerHTML = '';
document.getElementsByClassName('svg-container')[0].appendChild(element);
var newSvg = document.getElementById('svg');
newSvg.outerHTML = svg;
}
reader.readAsDataURL(this.fileToUpload);
}
HTML
<div class="svg-container">
<div id="svg"></div>
</div>
<div class="image-upload">
<label (click)='inputClick(Image)'>
<img src="image/upload.png" />
</label>
<input #Image type="file" (change)="handleFileInput($event.target.files)"/>
<button type="submit" class="btn-large btn-submit" [disabled]="Image.value=='' || !imageForm.valid"><i class="material-icons">save</i></button>
</div>
答案 1 :(得分:1)
快速回答.. @ guest271314(如果我以后能搞清楚的话,我会链接这个。)
这对我有用:
document.getElementById("dWorkSpace").ondrop = function(e) {
e.preventDefault(); //Default event loads the file itself.. KILL IT WITH FIRE.
if (!e.dataTransfer || !e.dataTransfer.items.length > 0 || !e.dataTransfer.files[0]) return;
var file = e.dataTransfer.files[0];
var reader = new FileReader(); //Make a reader
reader.onloadend = function (evt) { //When the file is actually loaded
Application.m_Two.interpretFromFile(Application.m_Two, reader.result);
}
reader.readAsDataURL(file);
}
更改的位是FileReader对象,我使用readAsDataUrl之类的 guest271314在第一条评论中谈到了。你能说出我是新人吗?的xD
演示:http://jonathancrowder.com/AnimatorProject/Application.html - 将SVG文件拖到页面上进行试用。
答案 2 :(得分:1)
如果要将外部svg文件包括在内嵌SVG中,则可以使用FileReader.readAsText()
函数以文本字符串的形式获取SVG的内容。
参考:https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsText
const reader = new FileReader();
reader.addEventListener("load", (event) => {
console.log(event.target.result);
});
reader.readAsText(file);
或者,如果要将其嵌入为Object或Img,则可以使用FileReader.readAsDataURL()
来获取SVG作为已编码的数据字符串,请参阅本文。
https://web.dev/read-files/
及其代码示例:
https://glitch.com/~read-image-file
const reader = new FileReader();
reader.addEventListener('load', event => {
document.getElementById('output').src = event.target.result;
});
reader.readAsDataURL(file);
答案 3 :(得分:0)
您必须从File对象创建一个BlobURL(它只是指向用户磁盘上文件的直接指针),然后设置<object>
&#39; s {{ 1}}到这个BlobURL。
这里我将使用一个data
元素,但它与任何Blob / File基本相同,无论它们来自哪里(请注意,虽然IIRC需要从{{<input>
方法调用getAsFile()
1}}&#39; s文件。
dataTransfer
&#13;
f.onchange = e =>{
var file = f.files[0];
if(file.type === 'image/svg+xml'){
var obj = document.createElement('object');
obj.data = URL.createObjectURL(file);
obj.onload = e => URL.revokeObjectURL(obj.data);
document.body.appendChild(obj);
}
};
&#13;