Svg image mask cut top and bottom - html

I need to create images with this shape:
http://imgh.us/image-mask_1.svg
First i try with css mask but the problem was support of browsers. So i jump over to svg image with mask inside.
I have a problem with SVG image where top and bottom part of the mask is cut off.
I have created a codepen to show you the problem:
<svg width="551" height="397" viewBox="0 0 551 397">
<defs>
<mask id="section_mask">
<image x="0.5" y="0.5" width="551" height="397" xlink:href="http://imgh.us/image-mask.svg" />
</mask>
</defs>
<image mask="url(#section_mask)" width="551" height="397" xlink:href="http://imgh.us/kh110512-22049-1-1024x682.jpg" />
</svg>
http://codepen.io/lasse_head/pen/ObJLKN
Thanks Lasse

It happens because the masked image has wrong width/height ratio.
The original image is 1024 x 682. The ration is 1.71788413. So, if you want to have height 397px, the width should be 397 x 1.71788413 = 596px . However, you set it to 551px.That was the reason for cutting.
<svg width="551" height="397" viewBox="0 0 551 397">
<defs>
<mask id="section_mask">
<image x="0.5" y="0.5" width="551" height="397" xlink:href="http://imgh.us/image-mask.svg" />
</mask>
</defs>
<image mask="url(#section_mask)" width="551" height="397" xlink:href="http://imgh.us/kh110512-22049-1-1024x682.jpg" />
</svg>

Related

Stretch an image into a SVG

I'd like stretch an image into a SVG but it seems not working as expected.
I used the preserveAspectRatio for the SVG but it doesn't work and the image get a padding left and right.
My code :
<svg class="mapSvg" preserveAspectRatio="none" width="1292px" height="649px" viewBox="0 0 1292 649">
<image xlink:href="https://images.sftcdn.net/images/t_app-cover-l,f_auto/p/befbcde0-9b36-11e6-95b9-00163ed833e7/260663710/the-test-fun-for-friends-screenshot.jpg" height="100%" width="100%" x="0" y="0"></image>
<polyline fill="red" stroke="black" points="461.909521484375,221.9047607421875 471.43330078125,220.9523681640625 475.24287109375,212.38095703125 472.385693359375,167.61904296875 477.147607421875,153.3333251953125 462.8619140625,153.3333251953125 460.95712890625,219.047607421875 461.909521484375,221.9047607421875" data-id="0">
</svg>
Main issue : my image do not fill the SVG.
Move preserveAspectRatio="none" to the image tag.
<svg class="mapSvg" width="1292px" height="649px" viewBox="0 0 1292 649">
<image preserveAspectRatio="none" xlink:href="https://images.sftcdn.net/images/t_app-cover-l,f_auto/p/befbcde0-9b36-11e6-95b9-00163ed833e7/260663710/the-test-fun-for-friends-screenshot.jpg" height="100%" width="100%" x="0" y="0"></image>
<polyline fill="red" stroke="black" points="461.909521484375,221.9047607421875 471.43330078125,220.9523681640625 475.24287109375,212.38095703125 472.385693359375,167.61904296875 477.147607421875,153.3333251953125 462.8619140625,153.3333251953125 460.95712890625,219.047607421875 461.909521484375,221.9047607421875" data-id="0">
</svg>

Inverse-fill svg shape

I want to make an horizontal s-curved shape where the bottom part of the shape is filled with a color.
When i use a quadratic bézier curve i get the shape that i want, but when i apply a fill color, the inside of the shapes get filled. See below
<svg width="400" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M0,30 Q100,0 200,30 T400,30" stroke="blue" stroke-width="1" fill="blue"/>
</svg>
I then tried do work with individual paths, which got me closer, but i want to reverse-fill the second path, but i have no idea how. This is my shape
<svg width="400" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M0,30 Q100,0 200,30" stroke="blue" stroke-width="1" fill="blue"/>
<path d="M200,30 Q300,60 400,30" stroke="blue" stroke-width="1" fill="none" />
<rect x="0" y="30" width="200" height="30" fill="blue" />
</svg>
How can i apply a filling color to the bottom side of the right curve?
If I understood the task correctly, you need to add three straight lines to your path (30px down from the end of the curve, then 400px left, and then 30px up, or just complete the path). You can use v, h, and Z commands in the same d attribute of the same path element for it:
<svg width="400" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M0,30 Q100,0 200,30 T400,30 v30 h-400 Z" stroke="blue" stroke-width="1" fill="blue"/>
</svg>

SVG curved text along a circle clip path element not displaying

Here's a link to my codepen: https://codepen.io/Bryandbronstein/pen/QVaQpa
So basically what I have is an svg circle set as a clipPath element to cut my image into a circle. Then I want to curve my text around the circle, rather than it being in a straight line on top of my circular image, like this:
image with curved text
The thing is, I have this image to show off as my example because this code works in Firefox, but no other browser I could test. What gives?
Here's my code:
<svg height="300" width="350">
<defs>
<clipPath id="circleView">
<circle id="curve" cx="150" cy="180" r="110" fill="transparent" />
</clipPath>
</defs>
<text x="390" y="-20" width="100">
<textpath id="homepageText" xlink:href="#curve">
My Homepage!
</textpath>
</text>
<image width="300" height="410" xlink:href="meee.jpg" clip-path="url(#circleView)" />
</svg>
Just to clarify, I have moderate experience in HTML and CSS but very little in SVG. Thank you!
Use path insted of circle, and text-anchor + startOffset to center the text:
<svg x="0px" y="0px" width="350" height="300" viewBox="0 0 350 300">
<defs>
<path id="curve" d="M40,180c0-60.751,49.248-110,110-110c60.751,0,110,49.249,110,110"/>
</defs>
<text fill="black" class="curved-text">
<textPath xlink:href="#curve" text-anchor="middle" startOffset="50%">My homepage!</textPath>
</text>
</svg>
Working Codepen.
Using svg path tag we can achieve curved text. Below is the modification to your code. Corrected x and y for text tag and have added path with id "forText.
<svg height="300" width="350">
<defs>
<clipPath id="circleView">
<circle id="curve" cx="150" cy="180" r="110" fill="transparent" />
</clipPath>
</defs>
<path id="forText" d="M32,110, C25,90, 180,-39,290,130" stroke="" fill="none"/>
<text x="0" y="35" width="100">
<textpath xlink:href="#forText">
My Homepage!
</textpath>
</text>
<image width="300" height="410" xlink:href="meee.jpg" clip-path="url(#circleView)" />
</svg>

Equivalent of "background-size: fill" for SVG <image> element

I have a situation where I have a SVG graphic whose width is a percentage of the viewport, and whose height is fixed. Inside the graphic I have an SVG image element which I want to always fill its immediate container without distorting, much as would be achieved by using CSS background-size: fill.
How can I achieve this using my SVG?
Here's a minimal setup of the problem (and a codepen):
<svg width=100% height=300>
<rect width=100% height=300 stroke="blue" stroke-width=30 fill="transparent" />
<image xlink:href="//unsplash.it/500/300" width=100% height=100% />
</svg>
In the above snippet, I need the image to fill the entire container without distorting (in this instance, the container being the root SVG), regardless of viewport width.
I can't switch to regular HTML because the graphic I'm working on has an SVG clipping mask applied to the image element.
I found this question, which seems close to what I'm asking, but I don't think answers my question:
How can I make my embedded svg image stetch to fill a container?
In hopes of avoiding the XY problem, here's the actual SVG graphic I'm working on. And the (fixed-height, variable-width) result I'm trying to achieve:
Svg scaling with image
If you add a viewbox to the svg the svg knows how to scale.
Now adding the same viewBox ratio as the svg makes it so the svg will always have the same scale as the image.
You can always scale the image to its inside the viewBox.
Then it will always scale with the svg.
svg {
border: 2px solid black;
}
<svg width="100%" height="100%" viewBox="0 0 500 300">
<image width="500" height="300" xlink:href="//unsplash.it/500/300"/>
</svg>
To keep the height of the image unchanged, set the fixed value of the viewport height and preserveAspectRatio = "none"
<svg width="100%" height="300" viewBox="0 0 500 300" preserveAspectRatio = "none">
<image width="500" height="300" xlink:href="//unsplash.it/500/300"/>
</svg>
UPD
The proportions of the picture will not change, the height remains fixed when using preserveAspectRatio="xMinYMin slice"
<svg width="100%" height="300" viewBox="0 0 500 300" preserveAspectRatio="xMinYMin slice">
<image width="100%" height="300" xlink:href="//unsplash.it/500/300" />
</svg>
UPD2
I looked your codepen Like the idea. I've finished it with your permission. Modified some parameters
<svg width="100%" height="400" preserveAspectRatio="xMinYMin slice">
<defs>
<mask id="clipping">
<rect width="100%" height="400" fill="white"/>
<ellipse cx="50%" cy="120%" rx="75%" ry="37%"/>
</mask>
<linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="white"/>
<stop offset="100%" stop-color="blue"/>
</linearGradient>
</defs>
<rect width="100%" height="400" fill="orange" mask="url(#clipping)" transform="translate(-20 12) rotate(-2.5)" />
<image xlink:href="https://unsplash.it/1000/500" width="100%" height="400" mask="url(#clipping)" transform="translate(0 -10)" />
<rect width="100%" height="400" fill="url(#Gradient1)" mask="url(#clipping)" transform="translate(0 -10)" opacity="0.25" />
</svg>
I ended up using two SVGs and an image which used a clipping mask defined in the first SVG to clip it down. I was able to make the SVGs scale by only defining a viewbox, not a width and height. I opted to use a fixed aspect ratio instead of a fixed height, percentage width, as I had originally planned.
body > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
img {
clip-path: url(#clipper);
}
<svg viewBox="0 0 1000 500">
<defs>
<symbol id="arch" viewBox="0 0 1000 400">
<path d="M0 0 H 1000 V 400 Q 500 300, 0 400" />
</symbol>
<clipPath id="clipper" clipPathUnits="objectBoundingBox">
<path d="M0 0 H 1 V 1 Q .5 .75, 0 1" />
</clipPath>
<linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
<stop offset="0%" stop-color="#87AFBF"/>
<stop offset="100%" stop-color="#002855"/>
</linearGradient>
</defs>
<use href="#arch" width="100%" y="-40" fill="#F9B000" transform="translate(-20 12) rotate(-2.5)" />
</svg>
<img src="//unsplash.it/1000/400" alt="">
<svg viewBox="0 0 1000 500">
<use href="#arch" y="-50" fill="url(#Gradient1)" opacity="0.75" />
</svg>
CodePen

Using embedded SVG inside a clip-path of an SVG

Trying to create a mask for an image using SVG. The mask is created out of a rounded corners rect, and a tip at the upper right corner.
I'm creating the entire thing just in SVG, but the I can't properly clip the tip of the mask. It seems as if you can't use an embedded SVG inside the clip-path element? Is that true? Whats the proper way to implement this than?
The image gets clipped only by the rectangle.
Here is my code -
<svg width="100%" height="210">
<defs>
<clipPath id="mask">
<rect rx="20" ry="20" width="calc(100% - 31px)" height="210" style="fill:red;"/>
<svg viewBox="0 0 33.5 18" width="44px" y="-93" x="calc(100% - 62px)">
<path fill="black" d="M23.5,10c0-5.5,4.5-10,10-10L0,0l0,18h23.5L23.5,10z"/>
</svg>
</clipPath>
</defs>
<image xlink:href="http://cdn.images.express.co.uk/img/dynamic/galleries/x701/58176.jpg"
x="0"
y="0"
width="100%"
preserveAspectRatio="none"
clip-path="url(#mask)"/>
</svg>
And a link to the codepen - http://codepen.io/itayd/pen/VpXLZW
The solution was to define the path element in the defs, and use a element inside the clipPath.
<svg width="100%" height="210">
<defs>
<path transform="translate(50%, 50%)" cx="100" d="M23.5,10c0-5.5,4.5-10,10-10L0,0l0,18h23.5L23.5,10z"/>
<path id="tip" fill="green" d="M37.5,24.4C37.5,11,48.5,0,62,0H0v34h37.5V24.4z"/>
<clipPath id="mask">
<rect rx="20" ry="20" width="calc(100% - 31px)" height="210" style="fill:red;"/>
<use xlink:href="#tip" x="calc(100% - 68px)"/>
</clipPath>
</defs>
<image xlink:href="http://cdn.images.express.co.uk/img/dynamic/galleries/x701/58176.jpg"
x="0"
y="0"
width="100%"
preserveAspectRatio="none"
clip-path="url(#mask)"/>
</svg>