はじめに
こんにちは。また久しぶりの投稿ですね。
WebアプリでSVG画像を出すのは、よくあることですね。しかし、SVG画像にシャドーをかけると、iOSのブラウザで開てみたら、画像がぼやけます。
これは困ります。
おそらくiOSのバグですが、いつ直すかわからない以上、直すまで待つのもいけないです。
代わりにPNG画像を出すのは解決できるが、ズームインしてもぼやけないために、大きいPNGを置かないといかないので、画像のサイズが増えます。
では、SVGを使う前提で、ぼやけるを防ぐ方法があるのでしょうか?ここで一つの解決策を紹介させていただきます。
問題点
上記通り、シャドーをかけているSVGをそのままwebに出すと、iOS上でぼやけます。
SVGは下記のようです。
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="paper-plane" class="svg-inline--fa fa-paper-plane fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<filter id="f1">
<feDropShadow dx="0" dy="2" stdDeviation="15" flood-color="black" />
</filter>
<path fill="currentColor" d="M476 3.2L12.5 270.6c-18.1 10.4-15.8 35.6 2.2 43.2L121 358.4l287.3-253.2c5.5-4.9 13.3 2.6 8.6 8.3L176 407v80.5c0 23.6 28.5 32.9 42.5 15.8L282 426l124.6 52.2c14.2 6 30.4-2.9 33-18.2l72-432C515 7.8 493.3-6.8 476 3.2z" filter="url(#f1)"></path>
</svg>
そして画像を出すソースコード(React Native)は下記のようです。
<View style={styles.imgContainer}>
<Image source={images.sample} tintColor={"#897654"} style={styles.img} />
</View>
// ...
imgContainer: {
width: 50,
height: 50,
marginVertical: 6
},
img: {
width: 50,
height: 50
}
解決策
SVG画像のサイズを何倍にして、スタイルにtransform
をつけて元のサイズに戻せば良い。
ソースコードを見てみましょう。
<Image source={images.sample} tintColor={"#897654"} style={styles.img} />
// ...
img: {
width: 200,
height: 200,
transform: [{scale: 0.25}]
}
上記の例で、50x50の画像が欲しいですが、4倍まで上げて200x200にして、またtransform
で1/4にして結局50x50にできました。
もちろん画像は200x200の領域を占めるが、これに対する処理も簡単です。
<View style={styles.imgContainer}>
<Image source={images.sample} tintColor={"#897654"} style={styles.img} />
</View>
// ...
imgContainer: {
alignItems: 'center',
justifyContent: 'center',
width: 50,
height: 50,
marginVertical: 6,
overflow: 'hidden'
}
上記のように、50x50のコンテナーを用意すれば、問題がないです。画像を真ん中に揃え、オーバーフローを隠せば、うまく表示されます。
改善結果
下記1つ目の画像はそのまま50x50で出し、iOS Safariで見た結果です。一方で、2つ目の画像は200x200かつtransform
をつけている画像です。この方法でぼやけることをちゃんと防ぎます。
参考資料
https://stackoverflow.com/questions/43546754/svg-icons-in-safari-are-blurred ←2017年ごろの質問なのに、今も参考になれるとは。iOS何とかしなさいよ。