feature image

2024年9月1日 | ブログ記事

@propertyを使ってCSSだけでエビを揉む

この記事はtraP 夏のブログリレー 14日目の記事です。

エビ揉め

エビ揉め自体が何であるかは説明しません

CSSだけでエビを揉む

本家の動きを観察すると、エビ部分と手部分がそれぞれ円運動していることがわかります。

cssにおいては、cos()sin()を用いて

#hand,
#shrimp {
  /* --angle を定義 */
  --angle: 0deg;

  /* --angle と --radius から位置を計算 */
  transform: translate3d(
    calc(var(--radius) * cos(var(--angle))),
    calc(-1 * var(--radius) * sin(var(--angle))),
    0
  );

  /* --angle を変化させる */
  animation: 0.53s linear momi infinite;
}

/* --angle を 0deg から 360deg まで変化させる */
@keyframes momi {
  from {
    --angle: 0deg;
  }

  to {
    --angle: 360deg;
  }
}

#shrimp {
  --radius: 10px;
}
#hand {
  --radius: 20px;
}

のように記述すれば動きそうです。

揉めない

実は上記のように記述するだけでは、期待通りにエビを揉むことはできません。

See the Pen 揉めない by detteiu8383 (@detteiu8383) on CodePen.

これはCustom PropertyのAnimation typediscreteであることに由来します。(https://www.w3.org/TR/css-variables-1/#defining-variables)

Notably, they can even be transitioned or animated, but since the UA has no way to interpret their contents, they always use the "flips at 50%" behavior that is used for any other pair of values that can’t be intelligently interpolated.
https://www.w3.org/TR/css-variables-1/#defining-variables

上記のコードでは--angle0degから360degまで変化させるように指定していますが、User AgentはCustom Propertyである--angleの具体的な値を解釈することができないため、中間地点でジャンプするようなアニメーションになってしまいます。

@keyframes momi {
  from {
    --angle: 0deg;
  }

  /* 具体的にどのように補完すべきかわからないため、中間地点でジャンプしてしまう */

  to {
    --angle: 360deg;
  }
}

結果、アニメーションによって--angle0degから360degに一気にジャンプするような挙動になり、円運動が描かれることはありません。

以下のように--angleを90度ずつ変化させるように指定すると、"ジャンプする"挙動がわかりやすいかもしれません。

@keyframes momi {
  0% {
    --angle: 0deg;
  }
  25% {
    --angle: 90deg;
  }
  50% {
    --angle: 180deg;
  }
  75% {
    --angle: 270deg;
  }
}

See the Pen 揉めない by detteiu8383 (@detteiu8383) on CodePen.

揉める

Custom Propertyを滑らかにアニメーションできなかったのは、UAがCustom Propertyの中身を解釈することができないからでした。
これを可能にする @property ルールと CSS.registerProperty() 関数があります。これらは今年7月から主要なブラウザエンジンの最新版でサポートされています(Baseline 2024)。

CSS プロパティと値 API - Web API | MDN
CSS プロパティと値 API(CSS Houdini API の傘下)により、 CSS カスタムプロパティの登録において、開発者は明示的に、プロパティの型チェック、既定値、プロパティの値を継承の有無の登録を行うことができます。
@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

または

window.CSS.registerProperty({
  name: "--angle",
  syntax: "<angle>",
  inherits: false,
  initialValue: "0deg"
});

このように記述することで、UAがCustom Property--angleの中身が<angle>であると解釈できるようになり、animationやtransitionで値が滑らかに遷移するようになります。

See the Pen 揉める by detteiu8383 (@detteiu8383) on CodePen.

CSSだけでエビを揉むことができました。やったね

おまけ

実際にこのエビ揉み原理を利用し、任意の画像にエビを揉ませることができるウェブページを作りました。

任意揉め
揉め

https://t.co/tZMziYEAL5 pic.twitter.com/ZVLzLA9TqI

— eyemono.moe (@eyemono_moe) August 29, 2024

明日の夏のブログリレー担当者は@zoi_dayoさんです。楽しみ~

d_etteiu8383 icon
この記事を書いた人
d_etteiu8383

グラフィック班とゲーム班とSysAd班所属 いろいろ活動しています

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2024年9月17日
1か月でゲームを作った #BlueLINE
Komichi icon Komichi
2024年8月21日
【最新版 / 入門】JUCEを使ってVSTプラグインを作ろう!!!!【WebView UI】
kashiwade icon kashiwade
2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2022年9月16日
5日でゲームを作った #tararira
Komichi icon Komichi
2024年8月29日
クロスコンパイルRust
H1rono_K icon H1rono_K
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記