パスワードを忘れた? アカウント作成
13956443 journal
日記

nakka-manの日記: JavaScriptで、CSSアニメーションを切り替える方法 4

日記 by nakka-man

アニメーション自体はCSSで書き、複数のアニメ挙動を JavaScript で切り替える方法について、Qiitaに書きました。

そんなの、CSSを classList で付けたり外したりすれば良いだけなんじゃ、と思って今までそうしていたのですが、オブジェクトが増えると、この classList の管理がだんだんと面倒になってくる。
色々テストしていたら、単にオブジェクトの style.animationName を書いてやるだけでアニメが動くことが判明。分かってしまえば、そりゃそうだって感じです。
ただし、同じアニメ名を書いた場合はアニメしません。一度クリアしてやる必要があるのです。

まあ、そこらへんとかを、CSS や JavaScript の初心者にも分かるようにサンプル付きで解説してみました。
ツッコミがありましたら、遠慮無くどうぞ。

  • left や transform の値は JavaScript からは読めないので、自分で計算して値を書かなければいけません(レンダリングエンジンが知っているはずの値を自分でも別途管理しなければいけないというのはイマイチな感じがしますね。何か良い方法はありますか?)。

    これは、JavaScriptから読めます。
    window.getComputedStyle() メソッド [mozilla.org]を使うと、要素の現在時点での計算済みスタイルを返すオブジェクト(CSSStyleDeclaration オブジェクト)を得ることができます。
    複雑なアニメーション中の要素も任意のタイミングでスタイルを取得できます。
    参考になりそうなQiita記事 [qiita.com]

    left の値は 42.123px のようにスタイルの文字列なので、スタイルそのものではなく移動量の数値が欲しい場合は、文字列をパースする必要があります。

    transform の値は matrix() 形式で返ってくるので、matrix(1,0,0,1,42.123,0) のような文字列をパースした上で、変形量を逆算する必要があります。
    matrix() のパース処理はまだブラウザ依存だったりするようなので、自前で実装したほうが無難でしょうか。CSSMatrix [mozilla.org]、DOMMatrix [mozilla.org]
    残念ながら translate() や rotate() や skew() を個別に得る方法はありません。
    拡大縮小や回転を伴う場合は、変形に transform-origin の指定も影響します。並行移動のみ行う要素の上に拡大縮小・回転を行う要素を乗せるパターンにして個別の transform を簡略化するのも一つの手ですね。
    また、transform は none が返る場合があることにも留意しましょう(パースできない場合は移動量0とみなすなど)。

    ここに返信
    • わぁ! 情報ありがとうございます!
      自分でも軽くググってみたのですがやり方は見つけられないでいました(私は物を探すのがヘタなんです。現実でもバーチャルでも)。
      参考になりました。ちょっと自分でも試してみます。

    • window.getComputedStyle() を試してみました。
      それで分かったことは、これで返って来る値は、自分がセットした値だと言う事です。
      例えば、left:100px から transform:translateX(200px) にアニメーションさせた後の値は、
          left: 100px
          transform: matrix(1, 0, 0, 1, 200, 0)
      が得られます。

      mozilla.org の解説で「計算し直した後 [w3.org]」の値を返すと書いてありますが、ここでの計算とはレンダリングエンジンが実行したリアルタイムな値では無く、設定した値を計算した物のようです。
      上述の例だと、translateX(200px) が matrix(1, 0, 0, 1, 200, 0) と計算されたのですね。
      念のため、window.getComputedStyle で返ってきた値を全て見てみましたが、残念ながら現在値はどこにも書かれていませんでした。

      考えてみれば、現在値が知りたければ、それは CSS style では無いですね。もっと奥深いところにあると想像できます。^^;

      実際にレンダリングエンジンが計算した値を得られれば、300.12px とかが得られたかもしれないと思います(イージグで小数点計算していると思うから誤差が入っている可能性があります。実際、アニメ後に値をセットし直すと1px動くことがあるっぽいです)

      でもまあ、いろいろ知見が得られました。
      情報提供に感謝致します!

typodupeerror

開いた括弧は必ず閉じる -- あるプログラマー

読み込み中...