動かない!?anime.jsでsvgのテキストアニメーションの作り方【fillのサンプル】

プログラミング学習

anime jsの使い方覚書です。

前半はqiitaに寄稿しました。後半は主にsvgアニメーションの解説です。

anime jsはtimeline内loopできない!?

タイムラインの最後でループさせようと思いました。

iconが上下に移動するコードですが、こういうコードでは1回しか実装されません。

.add({
  targets: '.icon-anime',
  loop: true,
  keyframes: [
    {
      translateY: [-20, 0],
      duration: 1000,
      easing: 'linear'
    },
    {
      translateY: [0, -20],
      duration: 1000,
      easing: 'linear'
    }
  ]
})

こういう画面はcompleteの使い所のようです。これでうまくいきました。

complete: () => {
  anime({
    targets: '.icon-anime',
    loop: true,
    keyframes: [
        {
          translateY: [-20, 0],
          duration: 1000,
          easing: 'linear'
        },
        {
          translateY: [0, -20],
          duration: 1000,
          easing: 'linear'
        }
    ]
  })
}

短くかくなら、direction: ‘alternate’を使うとよいです。座標飛びしないように基本的にこの書き方がよさそうです。

anime({
    targets: '.icon-anime',
    loop: true,
    direction: 'alternate',
    duration: 3000,
    translateY: -30,
    easing: 'linear'
})

keyframesはどちらかというと、loopではなく順番に実行するものに使った方がよさそうです。

スポンサーリンク

動かない!?anime.jsでsvgのpathアニメーションの作り方【サンプル】

svgのフォントが変わる原因はエスクポートデータがおかしい

illustratorやaffinity designer、クリスタでSVGファイルを作成します。

もっていない人はこの機会に契約や入手してもよいでしょう。

AdobeはxdがあったりAdobe fontsがついていたりすることがメリットです。

クリスタとaffinity designerは安価な買い切りです。

フォントはいい感じのものを用意します。フォントワークス などの有料フォントやフリーフォントがありますが、アウトライン化のライセンスを確認します。SVGはアウトライン化しますがHtmlに変換されるため組み込みとは別のようです。

データを作る際、注意事項があります。

1、アウトライン化して書き出す必要があります(勘違いする人は少ないかもですが、ラスタライズはピクセル化ですから違いますよ)。

2、文字が表示される順番がある場合、グラフィックソフトでデータを作る際に下側にあるデータから表示されるようなので1文字ずつ分割してデータを作っておきます。アウトライン化した時点でそうなるはずですが、テキストや図形が複数ある場合はこの点を注意しましょう。

3、グラフィックソフトによりますが、レイヤーなど日本語で名前をつけているとidが日本語になる場合があります。グラフィックソフト側で英語に変えとくべきでしょう。なお、グラフィックソフトによるかもしれませんが、非表示レイヤーの情報は書き出されないようです。

4、1つのアニメーショングループに対して、1つのSVGファイルがよいです。1回テキストやパーツごとに分けて書き出してテストしたのですが、座標調整が大変になります。1つのviewBoxで管理するとよいです。もしもマスクなどを作る場合は、VsCode上で切り分ける形にします。

svgの表示

エクスポートしたのち、SVGファイルを右クリックしてVsCodeで開きます。

そうするとSVGのデータを取得できます。

svgの部分をhtmlに埋め込むと表示できます。

<svg width="100%" height="100%">
</svg>

幅と高さは100%になっていましたが、削ってCSS側で指定してあげてもいいかもしれません。

svgのviewbox

viewboxは描画領域のことです。

viewBox="x, y, width, height"

下記の例は幅1200、高さ2100です。

<svg width="100%" height="100%" viewBox="0 0 1200 2100"

anime.jsでsvgのpathが動かない!?

あとはanime.jsでアニメーションさせるだけです。

とはいえ、最初、コピペするだけでは動きませんでした。動かない場合はidやclass名を見直しましょう。グラフィックソフトの階層構造や図形なのか否かによって名前が変わるようです。

pathにclassが全部あれば動くはずです。

<path class="text-anime'">
</path>
anime({
    targets: '.text-anime',
    strokeDashoffset: [anime.setDashoffset, 0],
    easing: 'easeInOutSine',
    duration: 500,
    delay(el, i) {
      return i * 3000
    }
})

実際は面倒なのでid pathなんか指定されて紹介されていますね。

targets: '#id path',

図形にclass名の指定がなかったため手動指定しました。

また文字や図形が線だと思っていたけど実は塗りだったというオチでも動きません。線にアニメをかけているわけなので。うっかりと塗りを書き出さないようにします。

複数指定

targets: '#id path, #id2 path, .class path, #shap rect, #shap path',

アウトラインはpath、図形はrectになっていました。他useなどいろいろあるようです。

fill(塗りつぶし)

タイムラインにすると線画アニメーションしたあと、塗りつぶせます。

const timeline = anime.timeline({
    targets: '#id path, #id2 path, .class path',
    direction: 'normal',
    loop: false
})
timeline.add({
    strokeDashoffset: [anime.setDashoffset, 0],
    easing: 'easeInOutSine',
    fill: ['transparent', 'transparent'],
    duration: 2000,
    delay(el, i) {
    return i * 150
    }
})
timeline.add(
    {
    easing: 'easeInOutSine',
    fill: ['transparent', '#ffffff'],
    duration: 500
    },
    '-=200'
)
スポンサーリンク

動かない!?anime.jsでsvgのマスクアニメーションの作り方【サンプル】

マスクアニメーションを利用すると手書きアニメーションが実現できます。

上記の方法は線画を描いて塗りです。ただ、文字を普通に描いていく方法がデザイン的にはしっくりきますし、企業サイトで使われているものはそっちの方が多いです。

まず、マスクの理解が必要です。

囲った場所が消えます。

<defs>
    <mask id="maskname">
        <!-- pathを入れる -->
    </mask>
</defs>
<image :href="require('~/assets/images/anime/sample.svg')" width="100%" height="100%" mask="url(#maskname)" />

ただ、こちら実際に作ってみましたが手間暇かかります。一応、ざっくりと解説してみました。

svgのマスクアニメーションの作り方

templeteをまとめるとこんな感じです。コンポーネント化した方がよいでしょう。

<template>
  <div>
    <b-row class="mx-0 my-0 py-5 px-0">
      <b-col cols="12">
        <div class="animebox box-centering">
          <div style="width: 800px;">
            <svg id="svg" x="0px" y="0px" viewBox="0 0 1200 600" xmlns="http://www.w3.org/2000/svg">
              <defs>
                <mask id="maskname">
                  <g id="mask"></g>
                </mask>
              </defs>
              <image
                :href="require('~/assets/images/anime/sample.svg')"
                width="100%"
                height="100%"
                mask="url(#maskname)"
              />
            </svg>
          </div>
        </div>
      </b-col>
    </b-row>
  </div>
</template>
スポンサーリンク

anime.js側でscaleすると座標がおかしくなる!transformが効かない!

scaleすると、次のCSSが効いていませんでした。!importantを使うとアニメーションしなくなるため、anime.js側で解決する必要がありそうです。

transform: translateX(-50%) translateY(-50%);

初期値で座標を固定してあげるとよさそうです。改善しました。

anime({
  targets: '.logo-anime',
  translateX: ['-50%', '-50%'],
  translateY: ['-50%', '-50%']
})

他に解決方法があれば知りたいところです。

簡単でしたが、参考になれば幸いです。

コメント

タイトルとURLをコピーしました