7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

完走賞を目指す @xrxoxcxoxAdvent Calendar 2022

Day 10

どうしてもCSSで単振動のアニメーションを作らないといけなくなったときに読む記事

Last updated at Posted at 2022-12-09

この記事の概要

色々な都合があって、CSSだけで単振動のアニメーションを実装しないといけなくなるタイミング、ありますよね。
そんなときにこの記事を読んでもらえれば解決します。

ネタです!

純粋なCSS

ひとまず完成形です。
(セットアップが楽なのでViteを使いましたが、Viteである意味はありません。)

以下で、近似した値を計算して、どうにか実装できました。
……こんなコード、絶対に手動で書きたくないですよね?

.element {
  animation: simple-harmonic-motion 2000ms linear infinite;
}

@keyframes simple-harmonic-motion {
  0% {
    transform: translateY(calc(100px * 0));
  }
  5% {
    transform: translateY(calc(100px * 0.30902));
  }
  10% {
    transform: translateY(calc(100px * 0.58779));
  }
  15% {
    transform: translateY(calc(100px * 0.80902));
  }
  20% {
    transform: translateY(calc(100px * 0.95106));
  }
  25% {
    transform: translateY(calc(100px * 1));
  }
  30% {
    transform: translateY(calc(100px * 0.95106));
  }
  35% {
    transform: translateY(calc(100px * 0.80902));
  }
  40% {
    transform: translateY(calc(100px * 0.58779));
  }
  45% {
    transform: translateY(calc(100px * 0.30902));
  }
  50% {
    transform: translateY(calc(100px * 0));
  }
  55% {
    transform: translateY(calc(100px * -0.30902));
  }
  60% {
    transform: translateY(calc(100px * -0.58779));
  }
  65% {
    transform: translateY(calc(100px * -0.80902));
  }
  70% {
    transform: translateY(calc(100px * -0.95106));
  }
  75% {
    transform: translateY(calc(100px * -1));
  }
    80% {
    transform: translateY(calc(100px * -0.95106));
  }
  85% {
    transform: translateY(calc(100px * -0.80902));
  }
  90% {
    transform: translateY(calc(100px * -0.58779));
  }
  95% {
    transform: translateY(calc(100px * -0.30902));
  }
  100% {
    transform: translateY(calc(100px * 0));
  }
}

PostCSSを使う

PostCSSはJavaScript製ですが、CSSと名前に入っているのでCSSだと言い張って使ってみます。

まずは必要なパッケージをインストールします。

npm i postcss postcss-cli postcss-for postcss-preset-env

次にpostcss.config.jsを作成します。

postcss.config.js
module.exports = {
  plugins: {
    "postcss-preset-env": {
      features: {
        "trigonometric-functions": true,
      },
    },
    "postcss-for": true
  },
};

package.jsonにコマンドを追加して、叩いておきます。

package.json
  {
    // 省略
    "scripts": {
+     "css:watch": "postcss style.css -o dist.css -w"
    },
  }

先ほど頑張って書いたCSSを以下のように編集します。
postcss-forによりループが指定できるようになり、postcss-preset-envtrigonometric-functionsにより三角関数が使えるようになります。

.element {
  animation: simple-harmonic-motion 2000ms linear infinite;
}

@keyframes simple-harmonic-motion {
  @for $i from 0 to 100 by 5 {
    $i% {
      transform: translateY(calc(100px * sin($i * 3.6deg)));
    }
  }
}

これにより、出力された結果は冒頭に載せたCSSと同じになります。

最後に

「CSSで三角関数が使えるようになるかも、みたいなニュースをいつか見たなあ」と思って調べたら、まだまだ先は長そうでした。

どうにか上手く実現できないかなあと考えていると、PostCSSを使えばできるかも……と浮かびました。
完全に実用性は無いコードなのですが、発想から実現までのプロセスとしては良かった気がして記事にしています。


最後まで読んでくださってありがとうございます!
Twitterでも情報を発信しているので、良かったらフォローお願いします!

Devトークでのお話してくださる方も募集中です!

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?