我想编写一个函数,当调用该函数时,将返回fabric canvas的SVG,其中所有文本元素都由路径替换。
这就是我到目前为止想出的
const toPath = async () => {
const myCanvas = new fabric.Canvas("render-canvas"); //create a canvas for converting
myCanvas.loadFromJSON(canvas.toJSON()); //copy the orignal canvas into it
const objects = myCanvas.getObjects();
objects.forEach((object, index) => { //iterate over all objects
if(object.type === "i-text") { //if i-text, get font and use opentype.js to generate path
if(object.fontFamily !== "") { //opentype.load is async returning a promise
opentype.load(process.env.PUBLIC_URL+"/fonts/ttf/"+getFontByName(object.fontFamily)["url"])
.then(font => {
const path = font.getPath(object.text, 0, 0, object.fontSize);
const fabricPath = new fabric.Path(path.toPathData(20), {
//some options, size, pos, color ect copied from original
});
console.log(index);
myCanvas.insertAt(fabricPath, index);
myCanvas.remove(object);
console.log(myCanvas.getObjects()); //contains correct paths
})
.catch(err => console.log("Error fetching font:", err));
}
}
});
//somewhere above I need to return a promise that is resolved when the loop is finished
return myCanvas; //wrong here, returns unconverted copy always because of promises
}我想像这样调用这个函数:
const pathCanvas = toPath();
// when all promises resolved
svg = pathCanvas.then(canvas => canvas.toSVG());现在,一旦整个循环成功运行,我如何在这里使用promise,使用fabric.toSVG()来解决它呢?
发布于 2021-04-27 21:13:41
下面是我现在解决这个问题的方法:我为所有的promises创建了一个空数组。在循环中,它使用promises填充,然后使用Promise.all()解析这些promises
const toPath = async () => {
//cut irrelevant fabric canvas initialization
//init empty array
let promises = [];
objects.forEach((object, index) => {
//in loop fill array with promises
promises = [...promises, new Promise((resolve, reject) => {
if(object.type === "i-text") {
if(object.fontFamily !== "") {
opentype.load(process.env.PUBLIC_URL+"/fonts/ttf/"+getFontByName(object.fontFamily)["url"])
.then(font => {
const path = font.getPath(object.text, 0, 0, object.fontSize);
const fabricPath = new fabric.Path(path.toPathData(20), {
//text options such as color, size, position ect
});
myCanvas.insertAt(fabricPath, index);
resolve(object); //I didnt know what to put here so I just resolve to object, its not used.
})
.catch(err => {
console.log("Error fetching font:", err);
reject(err);
});
} else {
reject("no fontFamily set");
}
} else { //any object not an i-text, just gets added
myCanvas.insertAt(object, index);
resolve(object);
}
})];
});
//resolve all promises
await Promise.all(promises);
//after all promises resolved, get svg of the fabric canvas
const svg = myCanvas.toSVG();
//return it
return svg;
}它是有效的,但是我不知道这是不是正确的方法,或者是否有更好的/更干净的方法。如果你知道这样的情况,请发表评论。Promises.all可能也可以与.then()和.catch()一起运行,但我不确定。
https://stackoverflow.com/questions/67272396
复制相似问题