使用fabric.js将canvas上的元素通过canvas.toJSON()转换为JSON后,要到另外一个页面上还原成原来的canvas。
需求是能够在canvas上绘制gif动图,fabric.js和原生canvas是不支持的,参考了fabricGif的做法实现了在canvas上绘制动图,实现的原理包括对fabric.Image的_render()方法的重写,要在另外一个页面的canvas上也实现绘制动图,我把fabricGif的做法同样运用到该页面中。在新页面中,我遍历JSON的objects,将里面类型为gif的对象拎出来(我使用另外一个对象记录canvas上所有元素的类型),对gif类型的对象采用fabricGif的方法进行绘制,然后将该对象在objects中剔除,最后使用canvas.loadFormJSON()绘制其他元素。
async function init () {
const canvasObjs = JSON.parse(canvasJSON) // canvasJSON 是原来的canvas序列化后的结果
const objects = Object.assign({}, canvasObjs.objects)
for (let i = 0; i < objects.length; i++) {
if (elementMap[i].type === "gif") {
await createGif(objects[i]); // 单独绘制gif元素
objects[i].isGif = 1
}
}
const finalObjs = objects.filter(item => item.isGif !== 1)
canvas.loadFormJSON(JSON.stringify(finalObjs)) // 绘制非gif元素
}
init();
然后问题就出现了:
当页面中只有一个动图时,它可以正常运行,但是当加上一个静态图片时,这个动图只显示第一帧之后就消失了。
我通过在那个重写的_render()方法中打log发现,在canvas上只有gif这一种图片类型元素时,_render()中的log可以随着fabric.util.requestAnimFrame的每次render正常打印,而在有其他静态图片类型元素时,这个log只会打印一次,而fabric.util.requestAnimFrame还是正常render。所以我怀疑在页面上有其他图片类型元素时,我重写的_render()会被再次重写,但是我没有证据,也不知道为什么会被重写,我甚至去看了fabric的部分相关源码,没看出什么端倪,可能是我比较菜、。。
然后我回到原来的那个canvas上,图片和gif是可以和谐共存的,原来的canvas上的静态图片,是通过fabric.Image.fromUrl()创建的,而另一个页面的canvas的静态图片,我是通过canvas.loadFromJSON()自动绘制的,意识到此处不同,我尝试在另外一个页面的canvas也采用相同的方法创建图片,然后问题就这样解决了。
function createImg (obj) {
const { left, top, scaleX, scaleY, src } = img
return new Promise((resolve) => {
fabric.Image.fromURL(src, img => {
img.set({
top,
left,
scaleX,
scaleY,
originX: 'center',
originY: 'center'
})
canvas.add(img)
resolve()
})
})
}
async function init () {
const canvasObjs = JSON.parse(canvasJSON) // canvasJSON 是原来的canvas序列化后的结果
const objects = Object.assign({}, canvasObjs.objects)
for (let i = 0; i < objects.length; i++) {
if (elementMap[i].type === "gif") {
await createGif(objects[i]); // 单独绘制gif元素
objects[i].isGif = 1
} else if (elementMap[i].type === "img") {
await createImg(objects[i]);
objects[i].isImg = 1
}
const finalObjs = objects.filter(item => item.isGif !== 1 && item.isImg !== 1)
canvas.loadFormJSON(JSON.stringify(finalObjs)) // 绘制非gif元素
}
init();
问题解决得有点稀里糊涂,我甚至还不清楚到底是什么原因导致我自定义的_render()方法没有正常执行,如果有懂行的大佬,希望不吝赐教,感激不尽!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)