今回のモチベーション
- デザイナーさんにアプリのスクショを送ったらlottieのパーツの色が少し濃いように見えるという話になった
- lottie-android: version. 3.0.7
- 問題のパーツは、透明度の指定されたレイヤーがいくつか重なっているもので、絵が重なっている領域と重なっていない領域とがある
- lottie-webのほうにjsonを食わせたものと見比べたら確かにAndroidのほうが濃かった。(意味があるかはわからないけど)Macのカラーピッカーで比較してみても表示環境の違い以上の差が確認できた
- lottie-web: version. 5.5.8
- カラーピッカーの実測値と設定値とを見比べると、
- webのほうは絵が重なっている領域も重なっていない領域も、レイヤーに指定された透明度とRGBそれぞれの値とを掛けた値が、実測値と一致した
- androidのほうは重なっている領域の実測値が上振れしていた
- レイヤーのブレンドモードに実装の違いがあるのではないかと予想してコードを読んだ
手短に言うと
- lottie-androidの仕様です
- コードをさんざん読んで何も分からんとなったあと、DESIGNERS_NOTE.mdというファイルに書いてあるのを発見し、心が無になった
- 子の要素を描くとき、親のレイヤーやグループに対して指定された不透明度は子の不透明度に掛け算しているとのこと*1
- 例えば下の図でいうと左側のような図を作りたかったとしても、lottie-androidでは右側のようになってしまう
https://jsfiddle.net/3yLgxdqs/
- (2019/9/29 1:53 追記) もうちょっとよく読んだら、このコミット: Fix rendering issue of translucent object overlapping (#1362) · airbnb/lottie-android@5e12628 · GitHub で親レイヤーに不透明度が指定されている場合にもoff screen renderingをやって正しい描画ができるようになる模様。次のバージョンで入るかな。
- (2019/10/15 0:29 追記) ver. 3.1.0がリリースされました。
setApplyingOpacityToLayersEnabled
のドキュメントを読んでねとのこと。- ちなみに私のパッチも取り込まれました。大した変更でもないのにいろいろと面倒をかけてしまった。。。
そのほかの雑多なこと
- レイヤーのブレンドモードは未実装
- Add support for multiply blend mode · Issue #1055 · airbnb/lottie-android · GitHub
- 今は順番に塗り重ねているだけ(source-overに相当)
- 最初はこれが怪しいと思っていた(実装されてなかったし)んだけど、問題のJSONを読んでみたら全部デフォルトのブレンドモード(source-over)だったのでもう何も分からんということになったのだった*2
- キャンバスサイズをはみ出すと涙目画質になってしまう
LottieDrawable.draw()
の中のコメントに書いてあることによると、Androidで確保できる画面のキャッシュサイズ以上の絵を描くことはできないので、絵を一旦キャンバスの中に納まるサイズで描いた後、本来の指定された大きさに引き延ばしているとのことLottieDrawable
を背景にセットするときにはBoundsの大きさに注意しよう