Masking an image with an existing SVG path - javascript

I have a set of SVG paths which make up a logo.
Then, I want to have several images (to appear as the SVG) which slide through gradually. My problem is that I cannot make them work as the background, in other words, I want the SVG to mask the image(s).
I have a SVG like this:
<svg class="polygon" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="225.533px" height="261.262px" viewBox="0 0 225.533 261.262" style="enable-background:new 0 0 225.533 261.262;" xml:space="preserve">
<g id="svg-draw">
<path data-name="nav-projects" data-href="<?php print JUri::base() ?>projects" data-ajax="true" class=" st4 hover-logo" d="M26.05,147.366c-4.384,10.375-21.823,47.717-24.713,71.831c-2.804,23.373,2.034,40.255,27.625,37.926c6.952-0.97,15.662-4.346,24.417-9.214"></path>
</g>
<image clip-path="url(#svg-draw)" height="100%" width="100%" xlink:href="<?php print THEME_URL."/img/rev1.jpg"; ?>" />
</svg>
And if you notice, I have put the image tag right inside the SVG. But nothing happens. I also have removed most of the Paths of the svg in the above example, because they are too long to be copied here.
I used the clip-path property of the image, but to no avail.

You can't just clip with any element. You have to define a <clipPath> and clip with that.
<svg class="polygon" version="1.1" id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="225.533px" height="261.262px"
viewBox="0 0 225.533 261.262">
<defs>
<clipPath id="svg-draw">
<path d="M26.05,147.366c-4.384,10.375-21.823,47.717-24.713,71.831
c-2.804,23.373,2.034,40.255,27.625,37.926
c6.952-0.97,15.662-4.346,24.417-9.214"></path>
</clipPath>
</defs>
<image clip-path="url(#svg-draw)" height="100%" width="100%"
xlink:href="http://placekitten.com/200/300" />
</svg>

Depending on the effect you wish to achieve, this CSS Tricks article should provide you with the right guidance https://css-tricks.com/clipping-masking-css/

Related

SVG icons in ReactJS

I have to move an SVG icon from a regular website to a ReactJS website. The SVG has to be modified a little to make it compatible with JSX, so I've removed all the ':'s and replaced them with camel case attribute names for JSX compatibility. The only issue is the d attribute.
The SVG now looks like:
<svg id="Logo" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="100px" viewBox="0 0 900 800" enable-background="new 0 0 1024 1024" xmlSpace="preserve">
<g id="Layer_1"></g>
<g id="Logo">
<g>
<g id="Fish">
<g>
<path style={{fill:"#8DC046"}} d="M430.249,525.415c0,64.563-58.349,136.165-58.349,136.165l0.434,0.435l214.046-136.867L374.238,388.279
l-0.594,0.596C373.644,388.875,430.249,458.241,430.249,525.415z"></path>
</g>
<g>
<path style={{fill="#B8CD43"}} d="M586.381,525.147L374.238,388.279l-0.594,0.596c0,0,56.605,69.366,56.605,136.54L586.381,525.147z"></path>
</g>
<g>
<path style={{fill="#15AADB"}} d="M430.249,253.264c0,64.145-56.444,136.163-56.444,136.163l0.433,0.435l212.143-136.868L372.334,116.125
l-0.595,0.598C371.739,116.723,430.249,188.18,430.249,253.264z"></path>
</g>
<g>
<path style={{fill="#4AC5ED"}} d="M586.381,252.994L372.334,116.125l-0.595,0.598c0,0,58.51,71.457,58.51,136.541L586.381,252.994z"></path>
</g>
<g>
<path style={{fill="#F88F2D"}} d="M596.473,389.394c0,216.894-135.035,388.081-135.035,388.081l0.789,0.795L889.707,388.9L462.227-0.467
l-1.095,1.097C461.132,0.629,596.473,177.202,596.473,389.394z"></path>
</g>
</g>
</g>
</g>
</svg>
This gives me the following error:
Module build failed: SyntaxError: Unexpected token (90:58)
This makes sense, but in the d attributes in my case there are parts like M596.473,389.394c0. As you can imagine, the letter c between the 4 and 0 cause issues as the letter is not an integer.
How can I make this SVG work without using a library or something else? I just want to convert this SVG to valid JSX.
Change style={{fill="#B8CD43"}} to style={{fill: "#B8CD43"}} every place, it will work.
There is no need of dangerouslySetInnerHTML. Here is the working Demo
React does not play nice with SVG yet. If your svg is static I personally find it much easier to do it this way:
var img = `<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 252.5 148.7" xml:space="preserve">
<g>
<polygon points="252.5,0 252.5,52.6"/>
</g>
</svg>`
In string you can put your svg exactly how you read it from file/DB without any extra conversions.
And then later use it in render like this:
<div dangerouslySetInnerHTML={{__html: img}}/>

SVG Pattern element wont resize in Chrome

I'm using inline svgs. I have a svg circle and fill it with a pattern. The image inside needs to 100% of container size. This works until the parent element gets resized.
When the parent element(div) gets resized via js the pattern wont reflect 100% width and height anymore.
This works in Firefox though.
To me it seems like the css doesnt get updated. If I change the value to 99% manually Chrome updates the size on both dimensions.
This is the structure of my svg:
<div style="height:150px; width:150px;">
<svg style="height:100%; width:100%;">
<defs>
<pattern id="image" x="0%" y="0%" width="100%" height="100%">
<image x="0%" y="0%" width="58%" height="58%" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="image.jpg"></image>
</pattern>
</defs>
<circle cx="50%" cy="50%" r="29%" fill="url(#image)">
</circle>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#other"></use>
</svg>
<div>
I had found similar questions, but without help:
Image inside svg pattern is blurried after zoom in Chrome (there the image gets blurry)
SVG <pattern> won't load when generated by Javascript (the question got closed without a good answer)
You need to add viewBox property in svg, please refer the following link:
https://css-tricks.com/scale-svg/
Updated Code -
function inc(){
var parent = document.getElementById('parent');
parent.style.width = '350px';
parent.style.height = '350px';
}
<div id='parent' style="height:150px; width:150px;">
<svg style="height:100%; width:100%;" viewBox="0 0 50 50">
<defs>
<pattern id="image" x="0%" y="0%" width="100%" height="100%">
<image x="0%" y="0%" width="58%" height="58%" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="image.jpg"></image>
</pattern>
</defs>
<circle cx="50%" cy="50%" r="29%" fill="url(#image)">
</circle>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#other"></use>
</svg>
<div>
Increase

custom svg filter not working on firefox

This below code works fine in chrome and filter is applied but fails in firefox. An extra space is also added by direct inclusion of svg definition in the html(This is present in all browsers). Not sure why its happening like this. Can someone let me know the issue, I am new to svg
Here is the codepen link: http://codepen.io/susheel61/pen/wJYgwr
<svg version="1.1" id="ThemeSvg">
<defs>
<g>
<!--/* Polygon definitions for overlay shape */-->
<rect id="red-poly" x="0%" y="0%" width="53%" height="100%" fill="#b5121b" transform="skewX(-10)"></rect>
<rect id="rect-fade-out" x="0%" y="0%" width="53%" height="100%" fill="url(#fade-out)" transform="skewX(-10)"></rect>
</g>
<g>
<filter id="red-angled-overlay" x="0%" y="0%" width="100%" height="100%">
<!--/* Bring in the mask for fading the image out */-->
<feImage xlink:href="#rect-fade-out" result="red-overlay" x="0" y="0"></feImage>
<!--/* Create composite of image and fade mask */-->
<feComposite in="SourceGraphic" in2="red-overlay" operator="out" result="composite"></feComposite>
<!--/* Bring in the colored polygon for the overlay */-->
<feImage xlink:href="#red-poly" result="overlay" x="0" y="0"></feImage>
<!--/* Blend the overlay with the faded image */-->
<feBlend in="composite" in2="overlay" mode="multiply"></feBlend>
</filter>
</g>
</defs>
</svg>
<svg version="1.1" viewBox="0 0 840 474" preserveAspectRatio="xMaxYMin slice">
<image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://wowslider.com/sliders/demo-10/data/images/autumn_leaves.jpg" width="100%" height="100%" filter="url(#red-angled-overlay)" class="svg-black-overlay"></image>
</svg>
Firefox does not support feImage filters where the image is a fragment. It only supports feImage where the image is a complete standalone image or a data URI of a complete SVG document.
You'd have to create two additional standalone SVG images one with each polygon definition in and point the feImage elements at the complete image document in each case.

Simple SVG Grid not being shown in IE 10 and IE 11

I got this little SVG grid
<svg id="grid-svg" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="smallGrid" width="10" height="10" patternUnits="userSpaceOnUse">
<path d="M 10 0 L 0 0 0 10" fill="none" stroke="#000000" stroke-width="0.7" />
</pattern>
<pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
<rect width="100" height="100" fill="url(#smallGrid)" />
</pattern>
</defs>
<rect x="-100%" y="-100%" width="200%" height="200%" fill="url(#grid)" />
</svg>
I got it in a template html. Because I don't want it to remain in the main page for a reason.
Then I just clone that piece of SVG, create a wrapper div, and append the grid-svg to it.
Then I apply the grid dynamically with jQuery.
It works for Chrome and Firefox, but it doesn't work for IE 10 and IE 11.
Do you know why?
Thanks.
I am using the SVG using D3.js and i had the same issue.
I wrote the below code to resolve the issue
$('#lineChartSVG g').remove();
$('#lineChartSVG path').remove();
here i am removing the previous g and path, replacing with the new one.
Keep your tags in the static content and then call the above code where you used your code. This should work
This was solved already, i was doing a jquery clone() to get it from the template, which is wrong. Now it works fine.

JavaScript - Is there a way how to draw SVG path UNDER the content?

I need a path that goes UNDER the content (text) - is there a way how to do that?
(as already been answered somewhere else, z-index doesnt affect svg paths)
You can declare PATH and TEXT in different SVG layers, and put one layer onto another like this
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:1">
<text x="100" y="15" fill="red">I love SVG</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:0">
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
http://jsfiddle.net/WJZrU/

Categories

Resources