発生した問題
何も考えずSVGで要素をclip-path
すると、切り抜きたい要素のサイズに合わせて切り抜いてくれませんでした。
問題発生時のコード
この問題が発生しているとき、みなさんのソースコードも以下と似た状態だと思います。
JSXなので少し記述がHTMLと異なりますが、読み替えていただけると幸いです。
// 切り取りたいSVGの形
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 103.758 103.758"
height={0}
width={0}
>
<clipPath id="super-ellipse">
<path
d="M64.36,13c35.815,0,52.4,15.545,52.4,51.36s-16.583,52.4-52.4,52.4S13,100.175,13,64.36,28.545,13,64.36,13Z"
transform="translate(-13 -13)"
fill="none"
/>
</clipPath>
</svg>
// 切り取る対象の要素
<img
src={profileImageSrc}
style={{ clipPath: 'url(#super-ellipse)' }}
/>
解決方法
- clipPathに
clipPathUnits="objectBoundingBox"
をつける - pathのサイズを
0-1
に正規化する
1.はそのままなのですが、2.のpathのサイズを正規化するというのが重要です。clipPathUnits="objectBoundingBox"
をつけると、pathがviewBoxの範囲ではなく、0-1
の範囲で描画されるようになります。
pathの項目一つ一つの数値をviewBoxの数値で割ることでも可能ではありますが、手っ取り早くtransformでscaleを指定しましょう。
scaleで指定する数値は、以下の計算で求めることができます。
1 / viewBoxの数値
transformでtranslate
等が指定されていれば、その数値もviewBoxの数値
で割る必要があります。
上記のコードの場合は、scaleに指定する数値は、
scale = 1 \div 103.758 = 0.009637
transformの数値は、
transform = -13 \div 103.758 = -0.125281
です。
解決後のコード
<svg>
<clipPath id="super-ellipse" clipPathUnits="objectBoundingBox">
<path
d="M64.36,
13c35.815,
0,
52.4,
15.545,
52.4,
51.36s-16.583,
52.4-52.4,
52.4S13,
100.175,
13,
64.36,
28.545,
13,
64.36,
13Z"
transform="translate(-0.125281 -0.125281) scale(0.009637)"
/>
</clipPath>
</svg>
// 切り取る対象の要素は同じ
ちなみに今回切り抜いたSVGの形は、スーパー楕円という図形です。
丸よりも丸みを感じる!? スーパー楕円の魅力とデザイン