この記事は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 typeがdiscreteであることに由来します。(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
上記のコードでは--angle
を0deg
から360deg
まで変化させるように指定していますが、User AgentはCustom Propertyである--angle
の具体的な値を解釈することができないため、中間地点でジャンプするようなアニメーションになってしまいます。
@keyframes momi {
from {
--angle: 0deg;
}
/* 具体的にどのように補完すべきかわからないため、中間地点でジャンプしてしまう */
to {
--angle: 360deg;
}
}
結果、アニメーションによって--angle
は0deg
から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)。
@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だけでエビを揉むことができました。やったね
おまけ
実際にこのエビ揉み原理を利用し、任意の画像にエビを揉ませることができるウェブページを作りました。
— eyemono.moe (@eyemono_moe) August 29, 2024