アニメーション可能なプロパティ一覧
どのスタイルプロパティを、どのプラットフォームでアニメーションできるかの一覧表です。公式の対応表を日本語で転記し、補足も添えました。
React Nativeでは、すべてのCSSプロパティがアニメーションできるわけではありません。ここでは、どのスタイルプロパティをどのプラットフォームでアニメーションできるかを一覧にまとめます。網羅性そのものが価値なので、要約せずに公式の対応表をそのまま転記しています。
react-native-svgのコンポーネントをアニメーションさせたい場合は、SVGのアニメーションを参照してください。
対応表
| プロパティ | Android | iOS | Web |
|---|---|---|---|
| flex | ✅ | ✅ | ✅ |
| flexBasis | ❌ | ❌ | ✅ |
| flexDirection | ✅ | ✅ | ✅ |
| justifyContent | ✅ | ✅ | ✅ |
| alignItems | ✅ | ✅ | ✅ |
| alignSelf | ✅ | ✅ | ✅ |
| alignContent | ✅ | ✅ | ✅ |
| flexGrow | ✅ | ✅ | ✅ |
| flexShrink | ✅ | ✅ | ✅ |
| flexWrap | ✅ | ✅ | ✅ |
| gap | ✅ | ✅ | ✅ |
| rowGap | ✅ | ✅ | ✅ |
| columnGap | ✅ | ✅ | ✅ |
| start | ✅ | ✅ | ❌ |
| end | ✅ | ✅ | ❌ |
| direction | ✅ | ✅ | ❌ |
| height | ✅ | ✅ | ✅ |
| width | ✅ | ✅ | ✅ |
| maxHeight | ✅ | ✅ | ✅ |
| maxWidth | ✅ | ✅ | ✅ |
| minHeight | ✅ | ✅ | ✅ |
| minWidth | ✅ | ✅ | ✅ |
| margin | ✅ | ✅ | ✅ |
| marginTop | ✅ | ✅ | ✅ |
| marginRight | ✅ | ✅ | ✅ |
| marginBottom | ✅ | ✅ | ✅ |
| marginLeft | ✅ | ✅ | ✅ |
| marginStart | ✅ | ✅ | ✅ |
| marginEnd | ✅ | ✅ | ✅ |
| marginBlock | ✅ | ✅ | ✅ |
| marginBlockEnd | ✅ | ✅ | ✅ |
| marginBlockStart | ✅ | ✅ | ✅ |
| marginInline | ✅ | ✅ | ✅ |
| marginInlineEnd | ✅ | ✅ | ✅ |
| marginInlineStart | ✅ | ✅ | ✅ |
| marginHorizontal | ✅ | ✅ | ✅ |
| marginVertical | ✅ | ✅ | ✅ |
| padding | ✅ | ✅ | ✅ |
| paddingTop | ✅ | ✅ | ✅ |
| paddingRight | ✅ | ✅ | ✅ |
| paddingBottom | ✅ | ✅ | ✅ |
| paddingLeft | ✅ | ✅ | ✅ |
| paddingStart | ✅ | ✅ | ✅ |
| paddingEnd | ✅ | ✅ | ✅ |
| paddingBlock | ✅ | ✅ | ✅ |
| paddingBlockEnd | ✅ | ✅ | ✅ |
| paddingBlockStart | ✅ | ✅ | ✅ |
| paddingInline | ✅ | ✅ | ✅ |
| paddingInlineEnd | ✅ | ✅ | ✅ |
| paddingInlineStart | ✅ | ✅ | ✅ |
| paddingHorizontal | ✅ | ✅ | ✅ |
| paddingVertical | ✅ | ✅ | ✅ |
| top | ✅ | ✅ | ✅ |
| left | ✅ | ✅ | ✅ |
| bottom | ✅ | ✅ | ✅ |
| right | ✅ | ✅ | ✅ |
| inset | ✅ | ✅ | ✅ |
| insetBlock | ✅ | ✅ | ✅ |
| insetInline | ✅ | ✅ | ✅ |
| insetBlockStart | ✅ | ✅ | ✅ |
| insetBlockEnd | ✅ | ✅ | ✅ |
| insetInlineStart | ✅ | ✅ | ✅ |
| insetInlineEnd | ✅ | ✅ | ✅ |
| position | ✅ | ✅ | ✅ |
| display | ✅ | ✅ | ✅ |
| overflow | ✅ | ✅ | ✅ |
| zIndex | ✅ | ✅ | ✅ |
| aspectRatio | ✅ | ✅ | ✅ |
| boxSizing | ❌ | ❌ | ✅ |
| backgroundColor | ✅ | ✅ | ✅ |
| color | ✅ | ✅ | ✅ |
| textDecorationColor | ❌ | ✅ | ✅ |
| textShadowColor | ✅ | ✅ | ✅ |
| borderColor | ✅ | ✅ | ✅ |
| borderTopColor | ✅ | ✅ | ✅ |
| borderBlockStartColor | ✅ | ✅ | ✅ |
| borderRightColor | ✅ | ✅ | ✅ |
| borderEndColor | ✅ | ✅ | ✅ |
| borderBottomColor | ✅ | ✅ | ✅ |
| borderBlockEndColor | ✅ | ✅ | ✅ |
| borderLeftColor | ✅ | ✅ | ✅ |
| borderStartColor | ✅ | ✅ | ✅ |
| borderBlockColor | ✅ | ✅ | ✅ |
| outlineColor | ✅ | ✅ | ✅ |
| shadowColor | ✅ | ✅ | ✅ |
| overlayColor | ❌ | ❌ | ❌ |
| tintColor | ✅ | ✅ | ❌ |
| shadowOffset | ❌ | ✅ | ✅ |
| shadowOpacity | ❌ | ✅ | ✅ |
| shadowRadius | ❌ | ✅ | ✅ |
| elevation | ✅ | ❌ | ❌ |
| textShadowOffset | ✅ | ✅ | ✅ |
| textShadowRadius | ✅ | ✅ | ✅ |
| boxShadow | ✅ | ✅ | ✅ |
| borderRadius | ✅ | ✅ | ✅ |
| borderTopLeftRadius | ✅ | ✅ | ✅ |
| borderTopStartRadius | ✅ | ✅ | ✅ |
| borderStartStartRadius | ✅ | ✅ | ✅ |
| borderTopRightRadius | ✅ | ✅ | ✅ |
| borderTopEndRadius | ✅ | ✅ | ✅ |
| borderStartEndRadius | ✅ | ✅ | ✅ |
| borderBottomLeftRadius | ✅ | ✅ | ✅ |
| borderBottomStartRadius | ✅ | ✅ | ✅ |
| borderEndStartRadius | ✅ | ✅ | ✅ |
| borderBottomRightRadius | ✅ | ✅ | ✅ |
| borderBottomEndRadius | ✅ | ✅ | ✅ |
| borderEndEndRadius | ✅ | ✅ | ✅ |
| borderWidth | ✅ | ✅ | ✅ |
| borderTopWidth | ✅ | ✅ | ✅ |
| borderStartWidth | ✅ | ✅ | ✅ |
| borderBottomWidth | ✅ | ✅ | ✅ |
| borderEndWidth | ✅ | ✅ | ✅ |
| borderLeftWidth | ✅ | ✅ | ✅ |
| borderRightWidth | ✅ | ✅ | ✅ |
| borderCurve | ❌ | ❌ | ❌ |
| borderStyle | ✅ | ✅ | ✅ |
| outlineOffset | ✅ | ✅ | ✅ |
| outlineStyle | ✅ | ✅ | ✅ |
| outlineWidth | ✅ | ✅ | ✅ |
| transformOrigin | ✅ | ✅ | ✅ |
| transform | ✅ | ✅ | ✅ |
| transformMatrix | ❌ | ❌ | ❌ |
| rotation | ❌ | ❌ | ❌ |
| scaleX | ❌ | ❌ | ❌ |
| scaleY | ❌ | ❌ | ❌ |
| translateX | ❌ | ❌ | ❌ |
| translateY | ❌ | ❌ | ❌ |
| backfaceVisibility | ✅ | ✅ | ✅ |
| opacity | ✅ | ✅ | ✅ |
| mixBlendMode | ✅ | ✅ | ✅ |
| fontFamily | ✅ | ✅ | ✅ |
| fontSize | ✅ | ✅ | ✅ |
| fontStyle | ✅ | ✅ | ✅ |
| fontVariant | ✅ | ✅ | ✅ |
| fontWeight | ✅ | ✅ | ✅ |
| textAlign | ✅ | ✅ | ✅ |
| textAlignVertical | ✅ | ❌ | ❌ |
| verticalAlign | ❌ | ❌ | ✅ |
| letterSpacing | ✅ | ✅ | ✅ |
| lineHeight | ✅ | ✅ | ✅ |
| textTransform | ✅ | ✅ | ✅ |
| textDecorationLine | ✅ | ✅ | ✅ |
| textDecorationStyle | ❌ | ✅ | ✅ |
| userSelect | ❌ | ❌ | ✅ |
| writingDirection | ❌ | ❌ | ❌ |
| includeFontPadding | ✅ | ❌ | ❌ |
| resizeMode | ✅ | ✅ | ❌ |
| objectFit | ❌ | ❌ | ❌ |
| cursor | ✅ | ✅ | ✅ |
| pointerEvents | ✅ | ✅ | ✅ |
| filter | ✅ | ✅ | ✅ |
| isolation | ❌ | ❌ | ✅ |
補足
スタイルの継承
スタイルの継承はサポートされていません。通常なら親から値を受け継ぐプロパティ(たとえばtextDecorationColorがcolorから継承する、といったもの)も、継承は実装されていないので、個別に指定する必要があります。
相対値(%)のマージン
Yogaは相対値(%)のマージンを、Webブラウザとは違うかたちで適用します。React Nativeでは、マージンは要素の寸法を変えずに、要素の間の空きとして加えられます。その結果、子要素とマージンの合計が親コンテナのサイズを超えると、親コンテナのサイズのほうが変わることがあります。
一方Webブラウザは、指定した相対マージンが親コンテナのなかで正しい量の空きを占めるように、要素そのものを縮めます。
単位が混在するマージン
絶対値(数値)と相対値(%)のマージンの間の補間は、親コンポーネントの寸法がマージンの影響を受ける場合、正しく動かないことがあります。これは実装上の問題で、親のサイズが変わる瞬間にアニメーションが速くなったり遅くなったりする、ペース配分の乱れとして現れます。
単位が混在する角丸
Yogaは角丸を、数値と相対値(%)とで違う計算をします。数値の場合は、丸めた角に接する2つの辺に同じ半径を適用します。相対値の場合は、辺の長さに応じて、短い辺と長い辺に別々の半径を適用します。現状では、絶対値(数値)と相対値(%)の間を正しく補間できません。
flexBasis
このプロパティは、アニメーション中の値そのものは正しく計算されますが、その値がビューに反映されません。flexGrowやflexShrinkといった他のflexプロパティは正しく動くので、アニメーションにはそちらを使ってください。
テキストシャドウのアニメーション
Web上では、テキストシャドウのスタイル(textShadowColor・textShadowOffset・textShadowRadius)をアニメーション中も保つために、そのすべてをアニメーションのキーフレームで指定する必要があります。iOSとAndroidにはこの制限がなく、意図どおりに動きます。
たとえば、影の色は固定して影の半径だけをアニメーションさせたい場合でも、WebではtextShadowColorを要素のスタイルにだけ書くのでは足りません。次のコードには問題があります。
<Animated.Text
style={{
animationName: {
from: {
textShadowRadius: 8, // 影の半径は8から
},
to: {
textShadowRadius: 16, // 16へ正しくアニメーションする
},
},
textShadowColor: 'red', // 🚨 この色はキーフレームで上書きされてしまう
// つまり、影は黒くなってしまう
}}>
Reanimated
</Animated.Text>
これを避けるには、textShadowColorをすべてのキーフレームで指定します。
<Animated.Text
style={{
animationName: {
from: {
textShadowColor: 'red', // 影は'red'で始まり
textShadowRadius: 8,
},
to: {
textShadowColor: 'red', // アニメーションの間も'red'を保つ
textShadowRadius: 16,
},
},
}}>
Reanimated
</Animated.Text>
CSSではtext-shadowは1つのプロパティですが、React Nativeでは色・オフセット・半径の3つに分かれています。そのためReanimatedは各キーフレームに既定値を補う必要があり、シャドウのスタイルは要素のスタイルオブジェクトからは継承されません。アニメーション中もスタイルを保つには、キーフレーム側で上書きする、というわけです。
ボックスシャドウのアニメーション
テキストシャドウと同じく、Web上ではシャドウのスタイル(shadowColor・shadowOffset・shadowOpacity・shadowRadius)をアニメーション中も保つために、すべてをキーフレームで指定する必要があります。加えてshadowOffset・shadowOpacity・shadowRadiusはAndroidのReact Nativeでは実装されていないため、アニメーションもできません。
これらの制限がないboxShadowプロパティの利用を強くおすすめします。boxShadowはAndroidでも動きます。
画像のティントカラーのアニメーション
iOSでtintColorプロパティをアニメーションさせるには、Imageコンポーネントが最初にレンダー(マウント)される時点でtintColorがスタイルオブジェクトに含まれている必要があります。最初に設定されていないと、このプロパティはCSSアニメーションやトランジションでは更新されません。