抽獎動畫

2023-01-13 21:00:30

svga動畫

本文介紹的動畫不是css,js動畫,是使用外掛播放svga檔案。

1.需求

UI同學在做一個春節活動,活動中需要有個開場動畫,原本想的簡單,不涉及介面呼叫邏輯,就直接用做一個gif圖片由前端來顯示就好了,但是這個gif做出來之後圖片太大了,頁面載入慢,如下圖1

gif圖片還有一個問題,透明部分會顯示成黑色,不符合預期。再者就是這個圖片太大了,有1.3M。

後來UI同學換了一種格式,apng動畫,APNG(Animated Portable Network Graphics)誕生於2004年,是PNG的點陣圖動畫擴充套件。可以簡單地理解為PNG格式的動畫版。但是UI同學做出來檔案體積更大了,這個檔案有2.9M,如下圖2

最後UI同學嘗試使用svga動畫,這種格式動畫體積小,只有33kb,但是有個問題svga檔案不能在瀏覽器中直接播放,需要參照第三方外掛,就誕生了這個需求。

2.思路

說是思路,其實就是使用svga外掛來播放這個動畫檔案,官方已經有說明檔案,只要照著這個檔案來寫就可以實現。

3.實現過程

這個專案是使用svelte來實現的,這個框架和vue有些類似,這裡不展開說明,只介紹如何實現這個播放功能。

3.1 canvas容器

svga播放使用canvas容器來播放,html程式碼如下圖:

<!-- svga播放器 -->
<canvas class="{['play-canvas', className].join(' ')}" on:click={onClick} bind:this={svgaCanvasEl}></canvas>

3.2 播放器

初始化播放器參考官方檔案照葫蘆畫瓢了,程式碼如下:

<script>
  import { onMount, onDestroy, createEventDispatcher } from 'svelte'
  import { Parser, Player } from 'svga'
  import {regExp} from '@/shared/internal/constants'

  //事件轉發
  const dispatch = createEventDispatcher()
  //svg容器
  let svgaCanvasEl = null
  //svg播放器
  let player = null
  //解析
  let parser = null
  //元件樣式
  export let className = ''
  //svga圖片地址
  export let svgaUrl = ''
  //暴露svga動畫設定
  export let playerConfig = {
    loop: 0,                //迴圈次數,預設值 0(無限迴圈)
  }
  //樣式
  export { className as class }

  const initSvgAnimation = async () => {
    if (svgaUrl) {
      try {
        if (!regExp.svgaSuffix.test(svgaUrl)) {
          throw 'inaccurate file format'
        }
        parser = new Parser()
        const svga = await parser.load(svgaUrl)
        player = new Player({
          container: svgaCanvasEl,
          fillMode: 'backwards',    // 最後停留的目標模式,預設值 forwards
          playMode: 'forwards',     //播放順序順序播放
          loop: 1,
          startFrame: 0,
          endFrame: svga.frames,
          isUseIntersectionObserver: false,
          isCacheFrames: false,
          ...playerConfig
        })
        await player.mount(svga)
        player.onStart = () => console.log('svg play onStart')
        player.onResume = () => console.log('svg play onResume')
        player.onPause = () => console.log('svg play onPause')
        player.onStop = () => console.log('svg play onStop')
        player.onProcess = () => {}
        player.onEnd = () => console.log('onEnd')
        await player.start()
      } catch (e) {
        console.error('svg play error:', e)
      }
    }
  }

  function onClick() {
    dispatch('click')
  }

  onMount(() => {
    initSvgAnimation()
  })

  onDestroy(() => {
    // 清空動畫
    player && player.clear() && player.destroy()
    // 銷燬
    parser && parser.destroy()
  })
</script>

3.3呼叫方式

呼叫方式如下:

<SvgaPlayer svgaUrl={popUpImg} playerConfig={playerConfig} class={"pageload-pop-svg"}></SvgaPlayer>

注意傳入兩個引數中第一個是svga檔案地址,可以是本地或者遠端cdn地址,第二個引數playerConfig是播放設定,覆蓋預設設定,參考官方檔案。
最後效果如下:

參考:
https://baijiahao.baidu.com/s?id=1681715610129777960&wfr=spider&for=pc
https://github.com/svga/SVGAPlayer-Web-Lite