Search code examples
svgclip

How to scale clipPath to svg bounding box


I'm trying to add a hexagonal shape over my image, which is working fine, however, the svg path size is much larger than my intended image size. I'd like the clipPath to be 108px 120px by the time it's loaded. My image is 240x240 for retina sake so it should scale down to 120px by 120px and fill the clipPath.

<svg width="108" height="120" viewBox="0 0 108 120">
  <defs>
    <clipPath id="svgPath">
      <path d="M73.61215932167728 7.499999999999999Q86.60254037844386 0 99.59292143521044 7.5L160.21469970012114 42.5Q173.20508075688772 50 173.20508075688772 65L173.20508075688772 135Q173.20508075688772 150 160.21469970012114 157.5L99.59292143521044 192.5Q86.60254037844386 200 73.61215932167728 192.5L12.990381056766578 157.5Q0 150 0 135L0 65Q0 50 12.99038105676658 42.5Z"></path>
    </clipPath>
  </defs>
  <foreignObject clip-path="url(#svgPath)" width="100%" height="100%">
    <img src="https://avatars3.githubusercontent.com/u/5648875?v=2&amp;s=240">
  </foreignObject>
</svg>

So far, I've applied a transform to the clipPath, which had better results, but it wasn't pixel perfect by any means, so I decided to keep looking. I also at one point converted the path to work with objectBoundingBox (which is this)

M0.751144482874 0.107142857143Q0.883699391617 0 1.01625430036 0.107142857143L1.63484387449 0.607142857143Q1.76739878323 0.714285714286 1.76739878323 0.928571428571L1.76739878323 1.92857142857Q1.76739878323 2.14285714286 1.63484387449 2.25L1.01625430036 2.75Q0.883699391617 2.85714285714 0.751144482874 2.75L0.132554908743 2.25Q0 2.14285714286 0 1.92857142857L0 0.928571428571Q0 0.714285714286 0.132554908743 0.607142857143Z

I thought this would enable me to be able to scale the clipPath up to the SVG container, but it didn't work. Otherwise, I've played around with width and height on img, foreignObject, clipPath, and svg to try and do what I'm wanting to do. I also have messed with viewBox. Anyway, I've been testing on Safari, so maybe that's part of my problem, but I was hoping that if it worked in Safari that it would also work in Firefox and Chrome.

Anyone have experience with this? I may just need to create the mask in Photoshop, but I was trying to challenge myself to do it this way.


Solution

  • Few corrected your first option. Add viewport svg - width="240" height="240" and added a transformation to the clippath transform="translate(30 0) scale(1.2)"

    <svg width="240" height="240" viewBox="0 0 240 240">
      <defs>
        <clipPath id="svgPath" transform="translate(15 0) scale(1.2)">
          <path d="M73.61215932167728 7.499999999999999Q86.60254037844386 0 99.59292143521044 7.5L160.21469970012114 42.5Q173.20508075688772 50 173.20508075688772 65L173.20508075688772 135Q173.20508075688772 150 160.21469970012114 157.5L99.59292143521044 192.5Q86.60254037844386 200 73.61215932167728 192.5L12.990381056766578 157.5Q0 150 0 135L0 65Q0 50 12.99038105676658 42.5Z"></path>
        </clipPath>
      </defs>
      <foreignObject clip-path="url(#svgPath)" width="100%" height="100%">
        <img src="https://avatars3.githubusercontent.com/u/5648875?v=2&amp;s=240">
      </foreignObject>
    </svg>
    If you need a responsive avatar, replace the digits viewport svg with percentages - width="25%" height="25%"

    <svg width="25%" height="25%" viewBox="0 0 240 240">
      <defs>
        <clipPath id="svgPath" transform="translate(15 0) scale(1.2)">
          <path d="M73.61215932167728 7.499999999999999Q86.60254037844386 0 99.59292143521044 7.5L160.21469970012114 42.5Q173.20508075688772 50 173.20508075688772 65L173.20508075688772 135Q173.20508075688772 150 160.21469970012114 157.5L99.59292143521044 192.5Q86.60254037844386 200 73.61215932167728 192.5L12.990381056766578 157.5Q0 150 0 135L0 65Q0 50 12.99038105676658 42.5Z"></path>
        </clipPath>
      </defs>
      <foreignObject clip-path="url(#svgPath)" width="100%" height="100%">
        <img src="https://avatars3.githubusercontent.com/u/5648875?v=2&amp;s=240">
      </foreignObject>
    </svg>

    option without <foreignObject>

    <svg width="50%" height="50%" viewBox="0 0 240 240">
      <defs>
        <clipPath id="svgPath" transform="translate(15 0) scale(1.2)">
          <path d="M73.61215932167728 7.499999999999999Q86.60254037844386 0 99.59292143521044 7.5L160.21469970012114 42.5Q173.20508075688772 50 173.20508075688772 65L173.20508075688772 135Q173.20508075688772 150 160.21469970012114 157.5L99.59292143521044 192.5Q86.60254037844386 200 73.61215932167728 192.5L12.990381056766578 157.5Q0 150 0 135L0 65Q0 50 12.99038105676658 42.5Z"></path>
        </clipPath>
      </defs>
     
    
      <image xlink:href="https://avatars3.githubusercontent.com/u/5648875?v=2&amp;s=240" clip-path="url(#svgPath)" width="240" height="240"> </image>
      </svg>

    UPD

    If necessary, you can change the scale and positioning of the picture relative to the frame, changing the digits of the image transformation command

    transform="translate(15 0) scale(1.2)"
    

    Example of an avatar with a shadow

    As a shadow, the second hexagon will be used, which moves to the right and down 4 pixels relative to the first hexagon.

    The edges of the hexagon are blurred with a Gaussian filter.

    <filter id="Filtershadow" height="120%" width="120%">
          <feGaussianBlur in="SourceAlpha" stdDeviation="4"/>     
    

    <svg width="50%" height="50%" viewBox="0 0 300 300">
      <defs>
        <clipPath id="svgPath" transform="translate(10 0) scale(1.2)">
          <path d="M73.61215932167728 7.499999999999999Q86.60254037844386 0 99.59292143521044 7.5L160.21469970012114 42.5Q173.20508075688772 50 173.20508075688772 65L173.20508075688772 135Q173.20508075688772 150 160.21469970012114 157.5L99.59292143521044 192.5Q86.60254037844386 200 73.61215932167728 192.5L12.990381056766578 157.5Q0 150 0 135L0 65Q0 50 12.99038105676658 42.5Z"></path>
        </clipPath> -->
      
      <filter id="Filtershadow" height="120%" width="120%">
          <feGaussianBlur in="SourceAlpha" stdDeviation="4"/> 
      </defs>
      
      <path id="shadow" transform="translate(14 4) scale(1.2)" fill="grey"  filter="url(#Filtershadow)" d="M73.61215932167728 7.499999999999999Q86.60254037844386 0 99.59292143521044 7.5L160.21469970012114 42.5Q173.20508075688772 50 173.20508075688772 65L173.20508075688772 135Q173.20508075688772 150 160.21469970012114 157.5L99.59292143521044 192.5Q86.60254037844386 200 73.61215932167728 192.5L12.990381056766578 157.5Q0 150 0 135L0 65Q0 50 12.99038105676658 42.5Z"></path>
    
      <image xlink:href="https://avatars3.githubusercontent.com/u/5648875?v=2&amp;s=240" clip-path="url(#svgPath)" width="240" height="240"> </image> -->
      </svg>