SVG reference external pattern ID - html

I have two SVG's - one being logo of rectangle shapes and the other being a single svg of a pattern image for the background.
The logo gets repeated across the document multiple times and when the <rect> is set to be filled by #rect-fill, the multiple instances of the pattern svg with id of #rect-fill elements breaks it and the background image does not show, so now I seperated them.
Now, since the pattern id is outside of the #rect-container svg, the pattern image does not show and no image can be loaded.
Is there anyway to reference a pattern for a rect outside of its containing <svg> in another <svg>?
<!-- the logo svg -->
<svg id="rect-container" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- left squares -->
<rect />
<rect />
<rect />
<!-- right squares -->
<rect />
<rect />
<rect />
</svg>
<!-- the background image pattern -->
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<pattern id="rect-fill" patternUnits="userSpaceOnUse" x="0" y="0" width="1112" height="100%">
<image xlink:href="../assets/images/hero.png" width="100%" height="100%" preserveAspectRatio="xMinYMid slice"/>
</pattern>
</svg>
<style>
/* Reference the pattern outside of the rect's svg */
#rect-container rect {
fill(#rect-fill);
}
</style>

First, you need to create one svg as a resource available to the others using <defs>.
<!-- the background image pattern -->
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<defs>
<pattern id="rect-fill" patternUnits="userSpaceOnUse" x="0" y="0" width="1112" height="100%">
<image xlink:href="../assets/images/hero.png" width="100%" height="100%" preserveAspectRatio="xMinYMid slice"/>
</pattern>
</defs>
</svg>
Then you will be able to reuse this element. More information here
<!-- the logo svg -->
<svg id="rect-container" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- left squares -->
<rect fill="url(#rect-fill)"/>
</svg>

Related

How can I isolate parts of a page so that ids are not looked up in different svgs?

Here the use element in the other svg refers to an elements in the first svg.
<!-- isolate me -->
<svg>
<rect id ="a" x="0" y="0" width="10" height="10"/>
<use href="#a" fill="red" x="0" y="0" />
</svg>
<!-- isolate me -->
<svg>
<use href="#a" fill="blue" x="0" y="0" />
</svg>
Is it possible to isolate parts of a page so that ids are not looked up in different parts of the page?
Further requirements:
As few obstructions as possible to manipulating it all with JavaScript

svg responsive with background-size cover for image

I've almost finished my background but it's not working properly, I'm trying to get the image to fit the viewbox dimensions. I need my image to responsive and to act like background-size:cover. I also need to have the scrollbars gone and I don't know why its there. Can someone help me get my image to fit the entire viewbox area and be responsive - I need it to be 100% width and 100% height and the image covered
codepen
<svg viewBox="0 0 490 500" width="100%" height="100%">
<defs>
<pattern id="hexagons" width="100%" height="100%">
<g id="svg" fill="black" x="0" y="0"></g>
</pattern>
<mask id="hexagon-halftone-mask">
<rect x="0" y="0" width="100%" height="100%" fill="url(#hexagons)" />
</mask>
</defs>
<image id="svg-bg" xlink:href="https://cdn.pixabay.com/photo/2016/09/07/11/37/tropical-1651426_960_720.jpg" mask="url(#hexagon-halftone-mask)"/>
</svg>

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>

How to crop a particular area of image with SVG clipping mask

I am doing a clipping mask through SVG clip path. I am using one SVG element with three clipping masking.
Problem is my svg is getting full window width and height, therefore images are also getting full width and height.
So what I want is to move the image inside the clipping path so that I can show the actual area of the image
Here is the Jsfiddle link.
I don't want to change the image's aspect ratio..
please let me know if there is any way for this .
Thanks
If you don't want your images to stretch and break their aspect ratio, then don't use preserveAspectRatio="none". You'll probably want to use one of the "xxx slice" variants. Below I have used different ones for each image in order to have them align to the left, centre and right repectively.
*{padding:0px; margin: 0px;}
html, body {width: 100%; height: 100%;}
<svg version="1.1" id="triagnleSvg" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
xml:space="preserve">
<clipPath id="last" clipPathUnits="objectBoundingBox">
<polygon points="1,0 .78,0 0.58,1 1,1"/>
</clipPath>
<clipPath id="first" clipPathUnits="objectBoundingBox">
<polygon points="0,0 0.4,0 0.218,1 0,1"/>
</clipPath>
<clipPath id="mid" clipPathUnits="objectBoundingBox">
<polygon points="0.4,0 0.78,0 0.58,1 0.218,1"/>
</clipPath>
<image class="topImage" clip-path="url(#mid)" preserveAspectRatio="xMidYMid slice" width="100%" height="100%" xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit3.jpg"/>
<!-- top -->
<image class="leftImage" clip-path="url(#first)" preserveAspectRatio="xMinYMid slice" width="100%" height="100%" xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit2.jpg"/>
<!-- right -->
<image class="rightImage" clip-path="url(#last)" preserveAspectRatio="xMaxYMid slice" width="100%" height="100%" xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit1.jpg"/>
</svg>
Update
[I am] still unable to get the exact view for the first image. I want to show the girl's face. but its not happening
One solution would be to change your images so that the area of interest is in the desired part of the image.
Otherwise you need to start working with viewBoxes. However, once a viewBox gets involved though, you can no longer stretch the parent SVG to fill the page width and height as per the original example. You'll have to be satisfied with a fixed aspect ratio for the image as a whole.
Here's one way to solve your problem:
*{padding:0px; margin: 0px;}
html, body {width: 100%; height: 100%;}
<svg version="1.1" id="triagnleSvg" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2 1">
<defs>
<clipPath id="mid" clipPathUnits="objectBoundingBox">
<polygon points="0.3,0 1,0 0.7,1 0,1"/>
</clipPath>
</defs>
<image class="leftImage" preserveAspectRatio="xMaxYMid slice" width="1" height="1"
xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit2.jpg"/>
<image class="rightImage" preserveAspectRatio="xMidYMid slice" x="1" width="1" height="1"
xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit1.jpg"/>
<image class="topImage" preserveAspectRatio="xMidYMid slice" x="0.5" width="1" height="1"
xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit3.jpg"
clip-path="url(#mid)"/>
</svg>
You might want to change the x (and maybe the y, too) for your images and apply the opposite translation to their corresponding clipping paths.
<!-- language: lang-html -->
<svg version="1.1" id="triagnleSvg" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none"
xml:space="preserve">
<clipPath id="last" clipPathUnits="objectBoundingBox" transform="translate(-200,0)">
<polygon points="1,0 .78,0 0.58,1 1,1"/>
</clipPath>
<clipPath id="first" clipPathUnits="objectBoundingBox" transform="translate(450,0)">
<polygon points="0,0 0.4,0 0.218,1 0,1"/>
</clipPath>
<clipPath id="mid" clipPathUnits="objectBoundingBox">
<polygon points="0.4,0 0.78,0 0.58,1 0.218,1"/>
</clipPath>
<image class="topImage" clip-path="url(#mid)" width="100%" height="100%" xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit3.jpg"/>
<!-- top -->
<image class="leftImage" clip-path="url(#first)" width="100%" height="100%" x="-450" xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit2.jpg"/>
<!-- right -->
<image class="rightImage" clip-path="url(#last)" width="100%" height="100%" x="200" xlink:href="http://testyourprojects.net/matrix/project/stackoverflowissue/kit1.jpg"/>
</svg>
However, if you are not fixing the minimum and maxumum width and height of the svg or its container, you might show blank parts of the image outside its boundaries. You can set min-height, max-height, min-width, or max-widthon the css for the svg or its container.
Also, since showing the interesting area rather depends on the device/browser width, an extra enhancement would be to automatically compute the exact translations to center the region of interest with a script, depending on the user's width.

Fill SVG image with pattern

I'm trying to fill SVG image with a pattern in HTML, but I'm not successfull. If I fill with the pattern path, it works. But I cannot apply it onto svg image.
Could you help me please?
Here is example.
Here is example code:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" width="400" height="400">
<defs>
<pattern id="image" x="0" y="0" width="400" height="400" patternUnits="userSpaceOnUse">
<image x="0" y="0" xlink:href="latka.jpg" width="100" height="100" />
</pattern>
</defs>
<image x="0" y="0" width="400" height="400" xlink:href="kosile.svg" fill="url(#image)"/>
</svg>
It makes no sense to apply a fill attribute to an embedded SVG. I assume what you were trying to do is create a tiled background on which to superimpose the linked SVG. The easiest way to do this is by adding a <rect> element filled with the background pattern, then put your embedded SVG image on top of this.
Here's an example:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="200" viewBox="0 0 200 200">
<defs>
<!-- define a pattern using a yellow tile image -->
<pattern id="bgimg" x="0" y="0" width="60" height="60"
patternUnits="userSpaceOnUse">
<image x="0" y="0" width="60" height="60"
xlink:href="http://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Shades_of_yellow.png/60px-Shades_of_yellow.png" />
</pattern>
</defs>
<!-- use this pattern to fill the SVG background -->
<rect x="0" y="0" width="200" height="200" fill="url(#bgimg)" />
<!-- Embed another SVG (purple circle) on top of this background -->
<image x="40" y="40" width="120" height="120"
xlink:href="http://upload.wikimedia.org/wikipedia/commons/5/5e/FF0084_circle.svg" />
</svg>