formatSvgToImg.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { Canvg, presets } from 'canvg'
  2. // https://gist.githubusercontent.com/n1ru4l/9c7eff52fe084d67ff15ae6b0af5f171/raw/da9fe36d72171d4e36b92aced587b48dc5182792/offscreen-canvas-polyfill.js
  3. if (!window.OffscreenCanvas) {
  4. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  5. // @ts-ignore
  6. window.OffscreenCanvas = class OffscreenCanvas {
  7. canvas: HTMLCanvasElement
  8. constructor(width: number, height: number) {
  9. this.canvas = document.createElement('canvas')
  10. this.canvas.width = width
  11. this.canvas.height = height
  12. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  13. // @ts-ignore
  14. this.canvas.convertToBlob = () => {
  15. return new Promise(resolve => {
  16. this.canvas.toBlob(resolve)
  17. })
  18. }
  19. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  20. // @ts-ignore
  21. return this.canvas
  22. }
  23. }
  24. }
  25. const preset = presets.offscreen()
  26. const blobToBase64 = (blob: any) => {
  27. return new Promise((resolve, _) => {
  28. const reader = new FileReader()
  29. reader.onloadend = () => resolve(reader.result)
  30. reader.readAsDataURL(blob)
  31. })
  32. }
  33. let canvas = null as any
  34. export const svgtopng = async (svg: any, width: any, height: any) => {
  35. console.log(canvas, +new Date() + '-----')
  36. if (!canvas) {
  37. canvas = new OffscreenCanvas(width, height)
  38. }
  39. const ctx = canvas.getContext('2d')!
  40. let v: any = await Canvg.fromString(ctx!, svg, preset)
  41. /**
  42. * Resize SVG to fit in given size.
  43. * @param width
  44. * @param height
  45. * @param preserveAspectRatio
  46. */
  47. v.resize(width * 2, height * 2, 'xMidYMid meet')
  48. // Render only first frame, ignoring animations and mouse.
  49. await v.start()
  50. const blob = await canvas.convertToBlob()
  51. const base64 = await blobToBase64(blob)
  52. // canvas.drawImage(base64
  53. // await v.stop()
  54. // releaseCanvas(canvas)
  55. ctx.clearRect(0, 0, canvas.width, canvas.height)
  56. // canvas = null
  57. console.log(canvas, 'draw')
  58. await v.stop()
  59. v = null
  60. return base64
  61. }
  62. // function releaseCanvas(canvasElement) {
  63. // // 清空 Canvas 上的内容
  64. // const ctx = canvasElement.getContext('2d')
  65. // ctx.clearRect(0, 0, canvasElement.width, canvasElement.height)
  66. // // 停止任何正在进行的动画或定时器
  67. // cancelAnimationFrame(canvasElement.animationId)
  68. // // 删除对 Canvas 元素的引用
  69. // canvasElement = null
  70. // }