kanzak72
@kanzak72

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

lottieを使ったアニメーションがスマホで見るとボヤける

解決したいこと

lottieを使ったアニメーションを制作しており
そのアニメーションをcssの transform:scaleやtransform-originを使って
様々な見せ方を模索しております。

その最中、scaleの拡大表示をした際
スマホ実機で閲覧するとボヤけたように見えてしまいます。
(pcのSafariでも同様のものが見えました)

svgアニメーションのため拡大しても問題はない認識でしたが
何故かボヤけたように見えてしまい
それの原因、改善策をご教授いただけますでしょうか。

pcでスマホサイズを閲覧時 (Chrome / モバイルビューシュミレーター)

pc.png

スマホ実機で閲覧時 (iPhone15 / Chrome)

sp.png

▼ html

<div class="anime">
     <div id="animation"></div>
</div>

▼ CSS


#animation {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}

#animation svg {
    opacity: 0;
}

.active #animation svg {
    animation: key-anime 9s cubic-bezier(1, 0.04, 0.43, 0.97);
    opacity: 1;
}

@keyframes key-anime {
    0% {
        transform: scale(7);
        transform-origin: 40% 10%;
    }

    50% {
        transform: scale(7);
    }

    100% {
        transform: scale(1);
        transform-origin: 50% 0%;
    }
}

▼ js

    //svg animation 設定
    var animation = lottie.loadAnimation({
        container: document.getElementById("animation"),
        renderer: "svg",
        loop: true,
        autoplay: true,
        path: "./assets/json/animation.json",
        rendererSettings: {
            preserveAspectRatio: 'xMidYMid meet'
        }
    });

自分で試したこと

下記がネットで調べて出た解決方法で
片っ端から使ってみたのですがダメでした。。。

    .anime,
    #animation,
    #animation svg {
        backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        will-change: opacity;
    }
0

1Answer

safariのバグですね、残念ながら長らく解決されず放置されてるものの一つです

対処法としては

(α):<svg>タグにanimationを指定せず内包の<path><circle><rect>に対してanimationを指定する

(β):<svg>タグにanimationを指定するのであれば拡大をしないようにする

などがあります

実装例(Mac/iOS safariで確認してみてください)

See the Pen for https://qiita.com/kanzak72/questions/a5829fee3936bd3e8c6b by southkey47 (@southkey47) on CodePen.

(β)の拡大しないについてもう少し詳しく書くとscale(1)より大きくしないという対処法になります

jpgやpngと同じく、画像サイズ以上に拡大しないことでぼやけを回避します

アニメーションさせないのであればいくら拡大して配置しても問題ないですが、アニメーション時のみ通常の画像と同じように扱うことで問題を回避するハックです

実装例のcodepenでは3倍の拡縮を指定していますが、scale(1)→scale(3)→scale(1)ではscale(1)より大きくなってしまうためぼやけが発生します

そのためscale(1)→scale(0.333)→scale(1)もしくはscale(0.333)→scale(1)→scale(0.333)というように指定することでscale(1)より大きくなるのを回避します

加えてsvg自体にも手を加えます

svg(レスポンシブ / アニメーション対応)
<svg xmlns="http://www.w3.org/2000/svg" width="180" height="180" viewBox="0 0 180 180">
  <circle cx="90" cy="90" r="30" fill="green" />
</svg>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180">
  <circle cx="90" cy="90" r="30" fill="green" />
</svg>
css(imgと同じ指定)
svg {
  max-width: 100%;
  height: auto;
}

widthとheightを取ってフルードイメージ化することでjpgやpngのように扱いやすくなりました

別途サイズ指定したい場合はmax-width等で調整するか、インラインブロック/ブロック要素で囲ってそちらにサイズを指定して対処します

svg(3倍化)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180">
  <circle cx="90" cy="90" r="90" fill="green" />
</svg>

実装例codepenでの拡縮が3倍なのでsvg自体を3倍拡大状態のサイズに設定します

これでscale(1)が変更前のsclae(3)相当になったので、scale(1)を超えないようアニメーションを設定します

css(アニメーション設定)
.animation-fix {
  animation: key-anime-fix 4s cubic-bezier(1, 0.04, 0.43, 0.97) infinite;
  opacity: 1;
  transform: scale(1);
  transform-origin: 50%;
}

@keyframes key-anime-fix {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(0.333);
  }

  100% {
    transform: scale(1);
  }
}
2Like

Your answer might help someone💌