Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use SVG clipPathUnits="objectBoundingBox"

I'm trying to use an SVG to mask an image.

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width=500 height=300>
    <defs>
    <clipPath id="clip">
    <path d="M2.16,1.363h23.699c13.739,0,24.899,10.74,24.899,23.999s-11.16...

<img width="500" style="clip-path: url(#clip);-webkit-clip-path: url(#clip);" />

It works but I want the clipPath size to match the media. In Chrome I can control the size of the clipPath with CSS but in FF the clipPath stays small. In Safari with one asset nothing appears and with another it appears off-center.

I've read other questions that talk about using clipPathUnits:

 <clipPath id="clip" clipPathUnits="objectBoundingBox">

But I cannot get this to work at all. Apparently it expects the paths units to be decimals... but my shape is too complicated to write by hand and I don't know of any design software that supports that format.

Update

Following Robert's comments, I tried adding a CSS transform to the clipPath to "translate" the units...

    #clip {
        -webkit-transform:scale(0.004195862879,0.005554321262);
        transform:scale(0.004195862879,0.005554321262);
    }

This allowed objectBoundingBox to work as expected in Chrome. But still no luck with Safari or FF. It appears that Safari still renders the clipPath outside the the element to be clipped... making it invisible. FF developer tools make it less clear where it's placing the clipPath.

like image 311
emersonthis Avatar asked May 20 '17 19:05

emersonthis


2 Answers

Run into this problem right now and found the solution. Thanks @RobertLongson for mentioning that when you applying clipPathUnits="objectBoundingBox", you should be sure that all of your coordinates are between 0 and 1. It means, that if you have, for example, a circle

<svg viewBox="0 0 20 20">
    <defs>
        <clipPath id="clip">
            <circle cx="10" cy="10" r="10" />
        </clipPath>
    </defs>
</svg>

then with clipPathUnits="objectBoundingBox" it should looks like this:

<svg>
    <defs>
        <clipPath id="clip" clipPathUnits="objectBoundingBox">
            <circle cx="0.5" cy="0.5" r="0.5" />
        </clipPath>
    </defs>
</svg>

In case of complex paths, I found one solution. All you need is an application for vector images editing. For Linux it could be Gravit Designer (I used it and it worked).

  1. Create new file of size 1x1
  2. Open you svg that contains your complex path without clipPath tag. If you don't have such source, then you can simply create new text file, paste your <path .../> into <svg>...</svg> and save it with *.svg extension, and then open it in your application (Gravit Designer).
  3. Copy your complex path from opened svg and paste it into created new file (1x1).
  4. Turn off "Preserve aspect ratio" (or something simillar) function if it enabled
  5. Set this parameters for your complex path: Width: 1px, Height: 1px, Top: 0px, Left: 0px.
  6. Save this 1x1 file as svg.
  7. Open this svg file in text editor and copy the value of d attribute.

Now you have your complex path in relative coordinates. Set it into you clip

...
<clipPath id="clip" clipPathUnits="objectBoundingBox">
    <path d="/* your copied value */" />
</clipPath>
...

Done! Now you can enjoy your responsive clip path without any additional transformations or other workarounds.

I know, it looks too complicated, but it really will be done in approximately 2 minutes (if you have vector image editing software installed).

Hope this helps someone despite of question was asked 1.5 years ago :)

like image 163
Limbo Avatar answered Oct 19 '22 20:10

Limbo


I was using Adobe Illustrator to try and shrink my vectors down to 1px by 1px, and it wasn't capturing all of the coordinates correctly. I instead found this awesome online tool that will convert SVG path coordinates to CSS clip-path friendly coordinates relative to a "1" unit without needing a vector editing program. The quality is much better than Illustrator and easier to use. 🙌

https://yoksel.github.io/relative-clip-path/

like image 20
Brenda Avatar answered Oct 19 '22 22:10

Brenda