Rectangle SVG Masking over video tag - html

I am trying to create a Mask over video tag.
I have below svg element which has transparent text but I am looking to have a rectangle shape instead of text.
I have also tried with polygon to create a rectangle but seems its not working.
<polygon points="0 0,0 100,300 100,300 0" fill="orange" />
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 285 80" preserveAspectRatio="xMidYMid slice">
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%" >
<rect x="0" y="0" width="100%" height="100%" />
<text x="72" y="50">OCEAN</text>
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" />
</svg>
svg {
width: 100%;
position:absolute;
top: 0;
left: 0; // needed for FF, Safari, Edge
height: 100%;
}
svg text {
font-family: Biko, sans-serif;
font-weight: 700;
text-transform: uppercase;
font-size: 38px;
}
svg rect {
fill: white;
}
svg > rect {
-webkit-mask: url(#mask);
mask: url(#mask);
-webkit-mask-mode: alpha;
mask-mode: alpha;
fill: black;
fill-opacity:0.8;
}

Was able to achieve using another rect element inside mask.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 285 80" preserveAspectRatio="xMidYMid slice">
<defs>
<mask id="mask" x="0" y="0" width="100%" height="100%" >
<rect id="svg-rect" x="0" y="0" width="100%" height="100%" />
<rect x="100" y="10" rx="5" ry="5" width="60" height="30"/>
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" />
</svg>

Related

How can I make this SVG mask responsive and keep the shadow at the bottom right of the circle? [duplicate]

This question already has answers here:
How to resize a svg
(2 answers)
Closed 17 hours ago.
I have the below SVG which I am using as a mask to overlay on an image, I am trying to make the circle responsive, so it shrinks on mobile devices but haven't had any luck using view box etc as it removes the mask, I am also trying to position the shadow to the bottom right of the circle, but again I am having trouble making it responsive.
Any help would be greatly appreciated.
svg {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2000 1000" preserveAspectRatio="xMidYMin slice">
<defs>
<mask id="mask" x="0" y="0">
<rect x="0" y="0" height="100%" width="100%" fill="#fff"/>
<circle cx="50%" cy="50%" r="250" />
</mask>
<pattern id="img" patternUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<image xlink:href="https://images.unsplash.com/photo-1507181179506-598491b53db4?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=299b6fae13eb39086f5bb28029c61760&auto=format&fit=crop&w=1778&q=80" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</pattern>
</defs>
<path id="Shadow" d="M462.231,0c19.593,38.355,29.045,88.448,36.926,138.3,9.125,75.59-104.323,237.333-194.755,250.24C246.323,389.921,51.569,371.964,0,313.148c46.559,91.147,141.283,153.59,250.655,153.59,155.395,0,281.365-125.97,281.365-281.365A280.22,280.22,0,0,0,462.231,0" opacity="0.2" />
<rect width="100%" height="100%" mask="url(#mask)" fill-opacity="1" fill="url(#img)" />
</svg>
Putting the path inside a g container allowed me to scale the shadow relative to the mask, hope this helps someone in the future.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 500 500" preserveAspectRatio="xMidYMid slice">
<defs>
<mask id="mask" x="0" y="0">
<rect x="0" y="0" height="100%" width="100%" fill="#fff"/>
<circle cx="50%" cy="50%" r="16.5%" />
</mask>
<pattern id="img" patternUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
<image xlink:href="https://images.unsplash.com/photo-1507181179506-598491b53db4?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=299b6fae13eb39086f5bb28029c61760&auto=format&fit=crop&w=1778&q=80" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</pattern>
</defs>
<g>
<path id="Shadow" d="m 462.231 0 c 19.593 38.355 29.045 88.448 36.926 138.3 c 9.125 75.59 -104.323 237.333 -194.755 250.24 c -58.079 1.381 -252.833 -16.576 -304.402 -75.392 c 46.559 91.147 141.283 153.59 250.655 153.59 c 155.395 0 281.365 -125.97 281.365 -281.365 a 280.22 280.22 0 0 0 -69.789 -185.373" opacity="0.2" style="transform: scale(0.3) translate(579px, 650px);" />
<rect width="100%" height="100%" mask="url(#mask)" fill-opacity="1" fill="url(#img)" />
</g>
</svg>

SVG file mask not being loaded with <use>

Let's say I have an SVG file test.svg
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="testsvg">
<mask id="mask3" x="0" y="0" width="100" height="100" >
<rect x="0" y="0" width="100" height="50"
style="stroke:none; fill: #ffffff"/>
<rect x="0" y="50" width="100" height="50"
style="stroke:none; fill: #666666"/>
</mask>
<rect x="1" y="1" width="100" height="100"
style="stroke: none; fill: #0000ff; mask: url(#mask3)"/>
</symbol>
</defs>
</svg>
If i try to use it like this in test.html
<svg>
<use href="test.svg#testsvg"/>
</svg>
The mask is not working I get a blue rectangle only. Doing an inspect element in firefox shows that the mask element is missing inside the shadow root. (Why ?)
The same thing as a direct inline SVG works just fine as expected, (I get two rectangles of different colors)
test2.html
<svg xmlns="http://www.w3.org/2000/svg">
<mask id="mask3" x="0" y="0" width="100" height="100" >
<rect x="0" y="0" width="100" height="50"
style="stroke:none; fill: #ffffff"/>
<rect x="0" y="50" width="100" height="50"
style="stroke:none; fill: #666666"/>
</mask>
<rect x="1" y="1" width="100" height="100"
style="stroke: none; fill: #0000ff; mask: url(#mask3)"/>
</svg>
Why is this happening?
Note To reproduce the above behavior security.fileuri.strict_origin_policy should be set to false in about:config in Firefox so that local files may be loaded

Red border in transparent ellipse if affected by the opacity of the container

this code
<svg viewbox="0 0 100% 100%" width="100%" height="400px">
<mask id="mask" x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" fill="#fff"/>
<ellipse cx="50%" cy="50%" rx="100" ry="150" stroke="red" stroke-width="10"/>
</mask>
<rect x="0" y="0" width="100%" height="100%" mask="url(#mask)" fill-opacity="0.7"/>
</svg>
return this as a result
I want to have this same result, but with a red border instead of gray in the ellipse and that this is not affected by the opacity of the rect.
I also need the inside of the ellipse to be transparent (not white) and that it is not affected by the opacity of the rect.
Is this possible?
If you are asking whether you can include a red ellipse as part of your mask, then the answer is no. Any colours in a mask are converted to alpha values.
If you want a red ellipse around your "hole", then you need to add it as a separate element on top of the rect.
body {
background-color: linen;
}
<svg viewbox="0 0 100% 100%" width="100%" height="400px">
<defs>
<!-- pull ellipse out as a reusable shape. Used by mask and for red border. -->
<ellipse id="one" cx="50%" cy="50%" rx="100" ry="150"/>
<mask id="mask" x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" fill="#fff"/>
<use xlink:href="#one" fill="black"/>
</mask>
</defs>
<rect x="0" y="0" width="100%" height="100%" mask="url(#mask)" fill-opacity="0.7"/>
<use xlink:href="#one" fill="none" stroke="red" stroke-width="10"/>
</svg>
for set order you can use tag use with the attribute xlink:href for more detail see this How to use z-index in svg elements?
add fill="#fff" tag and id="one" to ellipse and draw it again with <use xlink:href="#one"/>
<svg viewbox="0 0 100% 100%" width="100%" height="400px">
<mask id="mask" x="0" y="0" width="100%" height="100%">
<rect x="0" y="0" width="100%" height="100%" fill="#fff"/>
<ellipse id="one" cx="50%" cy="50%" rx="100" ry="150" stroke="red" fill="#fff" stroke-width="10"/>
</mask>
<rect x="0" y="0" width="100%" height="100%" mask="url(#mask)" fill-opacity="0.7"/>
<use xlink:href="#one"/>
</svg>

SVG percentage coordinate is off

I have three SVGs nested inside another SVG. The first one is supposed to be fluid and stretched out so preserveAspectRatio is none. The other two are set to 10% and 90% for the x value. But if you resize the page you'll see they have different distance from the left and right side. Why?
I'm expecting to see the left one having the same distance from left as the right one having the distance from right.
.box {
width: 60vw;
border: 1px dashed lightgray;
}
svg {
overflow: visible;
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50">
<svg viewBox="0 0 2 2" preserveAspectRatio="none">
<rect x="0" width="2" height="1" fill="#DDDDDD" />
</svg>
<svg x="10%" viewBox="0 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
<svg x="90%" viewBox="0 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
</svg>
</div>
Because you're starting to draw the second blue box at 90%, when you really want to end the draw at 90%. Fix this by setting the viewBox of the second blue box to:
viewBox="20 0 20 20"
Here's another solution.
The two blue SVGs are identical apart from their preserveAspectRatio attributes.
.box {
width: 60vw;
border: 1px dashed lightgray;
}
svg {
overflow: visible;
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50">
<svg viewBox="0 0 2 2" preserveAspectRatio="none">
<rect x="0" width="2" height="1" fill="#DDDDDD" />
</svg>
<svg x="10%" width="80%" height="100%" viewBox="0 0 10 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
<svg x="10%" width="80%" height="100%" viewBox="0 0 10 20" preserveAspectRatio="xMaxYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
</svg>
</div>
For anyone as confused as me, here is the problem:
If I set the viewBox x value to half of the width 10 / 2 = 5, then I technically panned the origin to the width's center.
.box {
width: 60vw;
border: 1px dashed lightgray;
}
svg {
overflow: visible;
}
<div class="box">
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="50">
<svg viewBox="0 0 2 2" preserveAspectRatio="none">
<rect x="0" width="2" height="1" fill="#DDDDDD" />
</svg>
<svg x="10%" viewBox="5 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
<svg x="90%" viewBox="5 0 20 20" preserveAspectRatio="xMinYMid">
<rect x="0" y="0" width="10" height="10" fill="#7FDBFF" />
</svg>
</svg>
</div>

Keep svg pattern scaling when resizing svg-shape

I have a svg-pattern applied to a polygon. It's working fine.
When I set another size on the svg-polygon, I don't want to scale the pattern.
I've tried all combinations I can think of with viewBox, patternUnits and patternContentUnits. The goal is to make the polygon work responsibly e.g. scale with it's parent element. Can anyone point me in the right direction?
<svg width="1000" fill="#ccc" viewBox="0 0 1440 60">
<defs>
<pattern id="pattern" x="0" y="0" width="900" height="600" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse">
<svg x="0" y="0" width="900.4" height="600" viewBox="0 0 900.4 600">
<!-- pattern code -->
</svg>
</pattern>
</defs>
<polygon points="0,0 1440,0 1440,20 0,60" x="0" y="0" stroke="#bbb" fill="url(#pattern)" />
</svg>
<svg width="500" fill="#ccc" viewBox="0 0 1440 60">
<defs>
<pattern id="pattern" x="0" y="0" width="900" height="600" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse">
<svg x="0" y="0" width="900.4" height="600" viewBox="0 0 900.4 600">
<!-- pattern code -->
</svg>
</pattern>
</defs>
<polygon points="0,0 1440,0 1440,20 0,60" x="0" y="0" stroke="#bbb" fill="url(#pattern)" />
</svg>
full example: https://codepen.io/anderssonola/pen/QqxKjJ
I solved temporarily by applying the pattern to a <rect>and then use css clip-pathto create the polygon and the pattern does not scale. I still would prefer to solve it with pure svg, since IE does not support the css clip-path.
.clip {
background: gray;
clip-path: polygon(0 0, 100% 0, 100% 30%, 0% 100%);
margin-bottom: 1em;
}
.clip.half {
width: 50%;
}
svg {
display: block;
height: 50px;
width: 100%
}
<div >
<svg>
<defs>
<pattern id="pattern" x="0" y="0" width="900" height="600" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse">
<svg x="0" y="0" width="900.4" height="600" >
<!-- pattern code -->
</svg>
</pattern>
<rect width="100%" height="50" fill="url(#pattern)" id="pattern-md"/>
</defs>
</svg>
</div>
<div class="clip">
<svg>
<use href="#pattern-md"/>
</svg>
</div>
<div class="clip half" >
<svg>
<use href="#pattern-md" />
</svg>
</div>
Working example: https://codepen.io/anderssonola/pen/oGyBMj/
You could always scale the pattern and size the polygon appropriately e.g.
<polygon transform="scale(2)" points="0,0 720,0 720,10 0,30" stroke="#bbb" fill="url(#pattern)" />