Reputation: 21
I want to add an image to SVG path. I tried at some level but it's a half-baked code and image is not taking a proper shape of SVG.
Here's the HTML for that:
<div class="top-fold">
<div class="curve-img" id="shapeContainer">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1280" height="564" viewBox="0 0 1280 564" preserveAspectRatio="none">
<defs>
<rect id="bg-a" width="1280" height="575"/>
<linearGradient id="bg-b" x1="50%" x2="71.552%" y1="-4.763%" y2="100%">
<stop offset="0%" stop-color="#FAFBFC"/>
<stop offset="100%" stop-color="#EBF3F9"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<mask id="bg-c" fill="#fff">
<use xlink:href="#bg-a"/>
</mask>
<path fill="url(#bg-b)" d="M0,0 L1280,0 L1280,465.166826 C1282.16971,484.337191 1283.83637,494.281583 1285,495 C1358.96463,540.665449 1275.63125,544.202225 1034,558.75895 C786.666667,573.659188 442,550.377565 0,488.914081 L0,0 Z" mask="url(#bg-c)"/>
</g>
</svg>
</div><!-- curve-img end -->
</div> <!-- top fold end -->
Here's the CSS for that.
.top-fold {
width: 100%;
position: relative;
height: 80vh;
}
.curve-img {
position: absolute;
height: 100%;
width: 100%;
background-size: cover;
top: 0;
left: 0;
z-index: 4;
}
#shapeContainer {
width: 100%;
height: 100%;
margin: auto;
background-image: linear-gradient(
to bottom,
rgba(255, 159, 63, 0.2),
rgba(255, 159, 63, 0.8)
),
url(https://www.nature.org/cs/groups/webcontent/@web/documents/media/2016-photocontest-yosemite-w-1.jpg);
background-size: cover;
background-position: center top;
overflow: hidden;
}
#shapeContainer svg {
display: block;
width: 100%;
height: 100%;
}
@media screen and (max-height: 400px) {
#shapeContainer {
background-size: auto 150%;
}
}
@media screen and (max-height: 200px) {
#shapeContainer {
background-size: auto 200%;
}
}
@media screen and (max-height: 100px) {
#shapeContainer {
background-size: auto 300%;
}
}
Here's the codepen link for your reference. https://codepen.io/enworl/pen/xPyMxL
Thanks in advance for your help.
Upvotes: 2
Views: 4460
Reputation: 101956
There is a lot in you sample, that I'm not sure about. A lot of it is unrelated to the main thrust of your question about having a mask with a curved bottom.
Anyway, creating the mask is actually quite simple. See the example below.
.top-fold {
position: relative;
width: 100%;
height: 80vh;
}
.curve-img {
position: absolute;
height: 100%;
width: 100%;
}
#shapeContainer svg {
display: block;
width: 100%;
height: 100%;
}
<div class="top-fold">
<div class="curve-img" id="shapeContainer">
<svg>
<defs>
<mask id="bg-c" maskContentUnits="objectBoundingBox">
<path fill="white"
transform="scale(0.000781, 0.001742)"
d="M0,0 L1280,0 L1280,465.166826 C1282.16971,484.337191 1283.83637,494.281583 1285,495 C1358.96463,540.665449 1275.63125,544.202225 1034,558.75895 C786.666667,573.659188 442,550.377565 0,488.914081 L0,0 Z"/>
</mask>
</defs>
<image xlink:href="https://www.nature.org/cs/groups/webcontent/@web/documents/media/2016-photocontest-yosemite-w-1.jpg"
width="100%" height="100%" preserveAspectRatio="xMidYMid slice" mask="url(#bg-c)"/>
</svg>
</div><!-- curve-img end -->
</div> <!-- top fold end -->
Note that there are still some quirks with applying masks to HTML content, so for now, the easiest approach is to put the image in the SVG instead.
I have removed the viewBox
and preserveAspectRatio="none"
from the SVG as we want it to scale up with its parent without distorting the image.
We are also switching the mask to use objectBoundingBox
units, so that it fits the image no matter what size it ends up as.
If you need the orange gradient wash on top, you can do it like this.
.top-fold {
position: relative;
width: 100%;
height: 80vh;
}
.curve-img {
position: absolute;
height: 100%;
width: 100%;
}
#shapeContainer svg {
display: block;
width: 100%;
height: 100%;
}
<div class="top-fold">
<div class="curve-img" id="shapeContainer">
<svg>
<defs>
<mask id="bg-c" maskContentUnits="objectBoundingBox">
<path fill="white"
transform="scale(0.000781, 0.001742)"
d="M0,0 L1280,0 L1280,465.166826 C1282.16971,484.337191 1283.83637,494.281583 1285,495 C1358.96463,540.665449 1275.63125,544.202225 1034,558.75895 C786.666667,573.659188 442,550.377565 0,488.914081 L0,0 Z"/>
</mask>
<linearGradient id="bg-b" x2="0" y2="1">
<stop offset="0%" stop-color="rgba(255, 159, 63, 0.2)"/>
<stop offset="100%" stop-color="rgba(255, 159, 63, 0.8)"/>
</linearGradient>
</defs>
<g mask="url(#bg-c)">
<image xlink:href="https://www.nature.org/cs/groups/webcontent/@web/documents/media/2016-photocontest-yosemite-w-1.jpg"
width="100%" height="100%" preserveAspectRatio="xMidYMid slice"/>
<rect width="100%" height="100%" fill="url(#bg-b)"/>
</g>
</svg>
</div><!-- curve-img end -->
</div> <!-- top fold end -->
Upvotes: 1
Reputation: 14585
You probably did not like the asymmetric form of the patch, that's how it looks like you.
I changed the form of the patch, but really, as Paul says, you need a layout from you, what you want to get.
New patch code:
<path d="M4 4 1278 0c1 137 0 330 0 420 0 89-304 140-639 139C399 557 1 518 3 427 4 355 4 4 4 4Z" fill="grey"/>
Your application with the new patch code:
.top-fold {
width: 100%;
position: relative;
height: 80vh;
}
.curve-img {
position: absolute;
height: 100%;
width: 100%;
background-size: cover;
top: 0;
left: 0;
z-index: 4;
}
#shapeContainer {
width: 100%;
height: 100%;
margin: auto;
background-image: linear-gradient(
to bottom,
rgba(255, 159, 63, 0.2),
rgba(255, 159, 63, 0.8)
),
url(https://www.nature.org/cs/groups/webcontent/@web/documents/media/2016-photocontest-yosemite-w-1.jpg);
background-size: cover;
background-position: center top;
overflow: hidden;
}
#shapeContainer svg {
display: block;
width: 100%;
height: 100%;
}
@media screen and (max-height: 400px) {
#shapeContainer {
background-size: auto 150%;
}
}
@media screen and (max-height: 200px) {
#shapeContainer {
background-size: auto 200%;
}
}
@media screen and (max-height: 100px) {
#shapeContainer {
background-size: auto 300%;
}
}
<div class="top-fold">
<div class="curve-img" id="shapeContainer">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1280" height="564" viewBox="0 0 1280 564" preserveAspectRatio="none">
<defs>
<rect id="bg-a" width="1280" height="575"/>
<linearGradient id="bg-b" x1="50%" x2="71.552%" y1="-4.763%" y2="100%">
<stop offset="0%" stop-color="#FAFBFC"/>
<stop offset="100%" stop-color="#EBF3F9"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<mask id="bg-c" fill="#fff">
<use xlink:href="#bg-a"/>
</mask>
<path fill="url(#bg-b)" d="M4 4 1278 0c1 137 0 330 0 420 0 89-304 140-639 139C399 557 1 518 3 427 4 355 4 4 4 4Z" mask="url(#bg-c)"/>
</g>
</svg>
</div><!-- curve-img end -->
</div> <!-- top fold end -->
It is necessary to remove vertical strips, somehow change the form, design? We are waiting for your layout and description.
Without vertical stripes
.top-fold {
width: 100%;
position: relative;
height: 80vh;
}
.curve-img {
position: absolute;
height: 100%;
width: 100%;
background-size: cover;
top: 0;
left: 0;
z-index: 4;
}
#shapeContainer {
width: 100%;
height: 100%;
margin: auto;
background-image: linear-gradient(
to bottom,
rgba(255, 159, 63, 0.2),
rgba(255, 159, 63, 0.8)
),
url(https://www.nature.org/cs/groups/webcontent/@web/documents/media/2016-photocontest-yosemite-w-1.jpg);
background-size: cover;
background-position: center top;
overflow: hidden;
}
#shapeContainer svg {
display: block;
width: 100%;
height: 100%;
}
@media screen and (max-height: 400px) {
#shapeContainer {
background-size: auto 150%;
}
}
@media screen and (max-height: 200px) {
#shapeContainer {
background-size: auto 200%;
}
}
@media screen and (max-height: 100px) {
#shapeContainer {
background-size: auto 300%;
}
}
<div class="top-fold">
<div class="curve-img" id="shapeContainer">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1280" height="564" viewBox="0 0 1280 564" preserveAspectRatio="none">
<defs>
<rect id="bg-a" width="1280" height="575"/>
<linearGradient id="bg-b" x1="50%" x2="71.552%" y1="-4.763%" y2="100%">
<stop offset="0%" stop-color="#FAFBFC"/>
<stop offset="100%" stop-color="#EBF3F9"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<mask id="bg-c" fill="#fff">
<use xlink:href="#bg-a"/>
</mask>
<path fill="url(#bg-b)" d="M-0.4 0.4 1282 0c0.9 137.1-0.5 330.3-0.5 419.6 0 89.3-307.6 140.5-643.3 138.7C398.7 557.1-2.5 518.2-1.1 426.8 0.1 354.6-0.4 0.4-0.4 0.4Z" mask="url(#bg-c)"/>
</g>
</svg>
</div><!-- curve-img end -->
</div> <!-- top fold end -->
Upvotes: 3