Convert Svg Path Data to 0-1 Range to Use as Clippath with Objectboundingbox

SVG Path 0 - 1 Range Conversion in Javascript

Use a regular expression with a global flag:

let nuPath = svgPath.replace(/(\d+(\.\d+)?)/g, replacer);

Also, you must define outside the function the width and height:

let svgHeight = 399.23;
let svgWidth = 1072.01;

And finally you must erase unused function arguments:

let count = -1;
function replacer(match) {
count++;
if (count % 2) {
return match / svgHeight;
} else {
return match / svgWidth;
}
}

How to use svg for clip path

There's a good answer here about calculating a clipPath's 0-1 range from the original SVGs dimensions.

.star {
width: 30px;
height: 30px;
clip-path: url(#star-clip);
background: Gold;
}

#rating {
display: flex;
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<defs>
<clipPath id="star-clip" clipPathUnits="objectBoundingBox" transform="scale(0.025, 0.02439)">
<path d="m3.885,14.64105l11.84103,0l3.65897,-12.22295l3.65897,12.22295l11.84103,0l-9.57958,7.55411l3.65916,12.22295l-9.57958,-7.55431l-9.57958,7.55431l3.65916,-12.22295l-9.57958,-7.55411z" />
</clipPath>
</defs>
</svg>

<div id="rating">
<div id="star-1" class="star"></div>
<div id="star-2" class="star"></div>
<div id="star-3" class="star"></div>
<div id="star-4" class="star"></div>
<div id="star-5" class="star"></div>
</div>

Using clipPathUnits=objectBoundingBox makes clip path disappear

When using clipPathUnits="objectBoundingBox" the width and height of the object bounding box of the clipping path are considered to have a length of 1 unit value.

In order to achieve this you either need to rewrite the d attribute of the path or you can scale the path. In this case I use transform="scale(0.00118,0.0017)"

 <clipPath id="wav" clipPathUnits="objectBoundingBox">
<path transform="scale(0.00118,0.0017)" id="thePath" d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.....

In order to know what value to use

  1. I get the bounding box of the path:

    let bb=thePath.getBBox();

  2. I use the bb.width and bb.height to get the scale:

    let sx = 1/bb.width;
    let sy = 1/bb.height

  3. I scale the path:

    thePath.setAttribute("transform", scale(${sx},${sy}))

body {
background: #333;
}

#hero {
background: url(https://source.unsplash.com/random);
height: 120vh;
background-color: #ff0000;
width: 100vw;
background-size: cover;
clip-path: url(#wav);
}

#hero2 {
background: url(https://source.unsplash.com/random);
height: 120vh;
background-color: #ff0000;
width: 100vw;
background-size: cover;
clip-path: url(#wav2);
}
<div id="hero"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<clipPath id="wav" clipPathUnits="objectBoundingBox">
<path transform="scale(0.00118,0.0017)" id="thePath" d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.6,0-19.6-13-38-13-15,0-14.9,11.1-38,11.1C672.5,33.1,676,4.6,640,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18s-32.8,15.9-49.9,15.9c-13.1,0-19.7-4-26.3-9.7h0c-6.5-5.6-13.2-13-26.3-13C375.8,19.7,376,35,356.9,35c-17.6,0-19.7-13-38-13-15.1,0-14.9,11.1-38,11.1C251.5,33.1,255,4.6,219,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18S43.3,42.4,26.3,42.4c-13.1,0-19.7-4-26.3-9.7V562.6c6.5,5.6,13.2,12.9,26.2,12.9,18.9,0,18.7-15.2,37.9-15.2,17.6,0,19.6,12.9,38,12.9,15,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.8-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6h0c6.5,5.7,13.2,13,26.3,13,18.9,0,18.7-15.2,37.8-15.2,17.6,0,19.7,12.9,38,12.9,15.1,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.9-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6V32.7C835.5,27.1,828.8,19.7,815.8,19.7Z" />
</clipPath>
</svg>

<div id="hero2"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<clipPath id="wav2" clipPathUnits="objectBoundingBox">
<path d="M815.8,19.7c-18.9,0-18.7,15.3-37.9,15.3-17.6,0-19.6-13-38-13-15,0-14.9,11.1-38,11.1C672.5,33.1,676,4.6,640,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18s-32.8,15.9-49.9,15.9c-13.1,0-19.7-4-26.3-9.7h0c-6.5-5.6-13.2-13-26.3-13C375.8,19.7,376,35,356.9,35c-17.6,0-19.7-13-38-13-15.1,0-14.9,11.1-38,11.1C251.5,33.1,255,4.6,219,4.6s-40.1,39.9-79.8,39.9c-33,0-38.7-18-63-18S43.3,42.4,26.3,42.4c-13.1,0-19.7-4-26.3-9.7V562.6c6.5,5.6,13.2,12.9,26.2,12.9,18.9,0,18.7-15.2,37.9-15.2,17.6,0,19.6,12.9,38,12.9,15,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.8-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6h0c6.5,5.7,13.2,13,26.3,13,18.9,0,18.7-15.2,37.8-15.2,17.6,0,19.7,12.9,38,12.9,15.1,0,14.9-11,38-11,29.4,0,25.9,28.5,61.9,28.5s40.1-39.9,79.8-39.9c33,0,38.7,18,63,18s32.9-15.9,49.9-15.9c13.1,0,19.7,4,26.3,9.6V32.7C835.5,27.1,828.8,19.7,815.8,19.7Z" />
</clipPath>
</svg>

SVG clipPath fit container and use % unit

You will have better luck, I believe, if you switch your clipPath to using bounding box units:

<clipPath clipPathUnits="objectBoundingBox" ... >

Then all your clip path coordinates should be defined in the range 0..1.

http://www.w3.org/TR/SVG/masking.html#EstablishingANewClippingPath

How to scale SVG coordinates in the range 0 and 1?

You don't need to do anything to the coordinates of the path. Instead, just transform the scale of the <clipPath>.

The path you want to use as your clipPath is 1280 x 670, so just apply the equivalent scale (1/1280, 1/670). This gives:

transform="scale(0.00078125, 0.001492537313433)"

This along with clipPathUnits="objectBoundingBox" means that you can use this shape to clip at any size or aspect ratio.

.cutR {  clip-path: url(#cutR)}
.blogMainArticleMedia { float: left; width: 100%}
.image { float: left; display: block; width: 100%}
<div class="blogMainArticleMedia cutR">  <img src="https://images.pexels.com/photos/459225/pexels-photo-459225.jpeg" alt="image" class="image"></div>
<!-- Viewbox has no effect --><svg viewBox="0 0 1280 670"> <defs> <clipPath transform="scale(0.00078125, 0.001492537313433)" id="cutR" clipPathUnits="objectBoundingBox"> <path d="M0 0C1.45 75.8834 320 74.5783 320 74.5783H960C960 74.5783 1280 75.1563 1280 149.157V522.048C1278.55 597.932 960 596.627 960 596.627H320C148.081 596.849 0.3 596.169 0 671.205V0Z"/> </clipPath> </defs></svg>

SVG clipping path scaling

Turns out the solution was the simple case of adjusting the scale from 0.01 to 0.001!

Updated working codepen

<img id="preview-img" width="100%" src="http://www.menucool.com/slider/prod/image-slider-4.jpg" style="clip-path: url("#clipPolygon");" class="moving">
<svg width="0" height="0" >
<clipPath id="clipPolygon" clipPathUnits="objectBoundingBox" transform="scale(0.001)">
<polygon id="poly1" points="317 543,966 254,964 -6,610 -5">
<animate id="poly1Anim" attributeName="points" dur="500ms" to="" fill="freeze" />
</polygon>
</clipPath>
</svg>


Related Topics



Leave a reply



Submit