何时能支持svga2.0呢
haliluya4 opened this issue · 7 comments
目前播放2.0版的svga动画,会直接报错。用SVGAPlayer-Web就可以播。
Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
at drawBezier (index.min.js:2:1)
at drawShape (index.min.js:2:1)
at eval (index.min.js:2:1)
at Array.forEach ()
at drawSprite (index.min.js:2:1)
at eval (index.min.js:2:1)
at Array.forEach ()
at render (index.min.js:2:1)
at e.drawFrame (index.min.js:2:1)
at animator.onUpdate (index.min.js:2:1)
目前播放2.0版的svga动画,会直接报错。用SVGAPlayer-Web就可以播。
Uncaught TypeError: Cannot read properties of undefined (reading 'replace') at drawBezier (index.min.js:2:1) at drawShape (index.min.js:2:1) at eval (index.min.js:2:1) at Array.forEach () at drawSprite (index.min.js:2:1) at eval (index.min.js:2:1) at Array.forEach () at render (index.min.js:2:1) at e.drawFrame (index.min.js:2:1) at animator.onUpdate (index.min.js:2:1)
大佬有找到解决方案吗?,我这边也遇到同样的问题
可以提供一下 svga 文件。2.0应该是支持的,可能是个问题。
@haliluya4 用的什么版本?我用 master 分支试验可以正常播放。
2.1.0的,通过npm install svga --save安装的。
在vue2的项目里,即使将这个文件放在public目录下,通过this.parser.load("./xxx.svga")的方式加载后,播放也是报同样的错。看起来文件是正常加载了,但是播放时出问题了。我们有其他的svga动画,也是2.0版本,也能正常播。
就是部分会报错。
代码类似以下这种
<canvas ref="player" v-if="localUrl"></canvas>
import { Parser, Player } from "svga";
this.localUrl = "./xxx.svga";
this.parser = new Parser();
this.parser.load(this.localUrl).then((svga) => {
if (this.isDestroyed) {
return;
}
if (!svga) {
console.error(`svga数据加载异常 ${this.localUrl}`);
return;
}
this.player = new Player(this.$refs.player as HTMLCanvasElement);
this.player.mount(svga).then(() => {
if (this.isDestroyed || !this.player) {
return;
}
this.player.start();
});
});
});
能否提供一个最小能重现的 Github Repo 地址带上有问题的 SVGA 文件?
能否提供一个最小能重现的 Github Repo 地址带上有问题的 SVGA 文件?
你好,我在使用svga的时候,遇到了同样的问题,经排查定位到问题出在是render.ts里的drawBezier函数,该函数的第二个入参d,replace操作没有处理d为undefined的异常,才导致运行时报错。以下是修改后的代码:
function drawSprite (
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
sprite: VideoSprite,
currentFrame: number,
bitmap: Bitmap | undefined,
replaceElement: ReplaceElement | undefined,
dynamicElement: DynamicElement | undefined
): void {
const frame = sprite.frames[currentFrame]
if (frame.alpha < 0.05) return
context.save()
context.globalAlpha = frame.alpha
context.transform(
frame.transform?.a ?? 1,
frame.transform?.b ?? 0,
frame.transform?.c ?? 0,
frame.transform?.d ?? 1,
frame.transform?.tx ?? 0,
frame.transform?.ty ?? 0
)
if (bitmap !== undefined) {
if (frame.maskPath !== null) {
drawBezier(context, frame.maskPath.d, frame.maskPath.transform, frame.maskPath.styles)
context.clip()
}
if (replaceElement !== undefined) {
context.drawImage(replaceElement, 0, 0, frame.layout.width, frame.layout.height)
} else {
context.drawImage(bitmap, 0, 0, frame.layout.width, frame.layout.height)
}
}
if (dynamicElement !== undefined) {
context.drawImage(dynamicElement, (frame.layout.width - dynamicElement.width) / 2, (frame.layout.height - dynamicElement.height) / 2)
}
// shape的path属性可能为空,所以需要判断
frame.shapes.forEach(shape => drawShape(context, shape))
context.restore()
}
function drawBezier (
context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,
d: string | undefined,
transform: Transform | undefined,
styles: VideoStyles
): void {
context.save()
resetShapeStyles(context, styles)
if (transform !== undefined) {
context.transform(
transform.a,
transform.b,
transform.c,
transform.d,
transform.tx,
transform.ty
)
}
const currentPoint: CurrentPoint = { x: 0, y: 0, x1: 0, y1: 0, x2: 0, y2: 0 }
context.beginPath()
if (d !== undefined) {
d = d.replace(/([a-zA-Z])/g, '|||$1 ').replace(/,/g, ' ')
d.split('|||').forEach(segment => {
if (segment.length === 0) return
const firstLetter = segment.substr(0, 1)
if (validMethods.includes(firstLetter)) {
const args = segment.substr(1).trim().split(' ')
drawBezierElement(context, currentPoint, firstLetter, args)
}
})
}
if (styles.fill !== null) {
context.fill()
}
if (styles.stroke !== null) {
context.stroke()
}
context.restore()
}