首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用opentype.js、fabric和promises在画布上将文本转换为路径

使用opentype.js、fabric和promises在画布上将文本转换为路径
EN

Stack Overflow用户
提问于 2021-04-27 03:05:26
回答 1查看 295关注 0票数 1

我想编写一个函数,当调用该函数时,将返回fabric canvas的SVG,其中所有文本元素都由路径替换。

这就是我到目前为止想出的

代码语言:javascript
复制
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
}

我想像这样调用这个函数:

代码语言:javascript
复制
const pathCanvas = toPath();
// when all promises resolved
svg = pathCanvas.then(canvas => canvas.toSVG());

现在,一旦整个循环成功运行,我如何在这里使用promise,使用fabric.toSVG()来解决它呢?

EN

回答 1

Stack Overflow用户

发布于 2021-04-27 21:13:41

下面是我现在解决这个问题的方法:我为所有的promises创建了一个空数组。在循环中,它使用promises填充,然后使用Promise.all()解析这些promises

代码语言:javascript
复制
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()一起运行,但我不确定。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67272396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档