making different parts of an SVG image clickable - svg

I have searched through the net and have come to discover that images are made clickable when they are converted to SVG format, however I am still not sure how to do this.
the image below for example, I need every box to be clickable, how do you go about doing this and is there any app that can help me, thank you in advance
enter image description here

You could do this with an SVG. But you would probably find it much easier to do with an HTML image map.

If you're able to edit the SVG itself you can wrap each element with an anchor tag.
<svg>
<a href="www.link1.com">
<rect x="10" y="10" width="60" height="50" fill="#ddd">
</a>
<a href="www.link2.com">
<rect x="75" y="10" width="60" height="50" fill="#ddd">
</a>
</svg>
Otherwise you can use Javascript to add a click handler to each element.
document.getElementById("rect1").addEventListener("click", function() {
window.open('www.link1.com')
});
document.getElementById("rect2").addEventListener("click", function() {
window.open('www.link2.com')
});
<svg>
<rect id="rect1" x="10" y="10" width="60" height="50" fill="#ddd"/>
<rect id="rect2" x="75" y="10" width="60" height="50" fill="#ddd"/>
</svg>

Related

How to alter how svg pattern fill is displayed

So I have a webpage here. Under "frame background" there are patterns. When clicked they display in the photo frame. The problem is that some of them seem really blocky. Particularly the last one.
My code for this.
jquery:
$(" #borders #pattern1").click (function() {
$(".border").css("fill", "url(#patt1)");
});
svg:
<defs>
<pattern id="patt1" patternUnits="userSpaceOnUse" width="400" height="500">
<image xlink:href="Images/pattern1.jpg" x="0" y="0" width="542" height="774" />
</pattern>
</defs>
I hope this makes sense. If down voting for some reason please give me feedback as to why.

Using SVG logo as mask

I'm basing my exercise on the accepted answer in: Creating transparent text to show gradient color of underlying div
Here's my rendition in jsfiddle: http://jsfiddle.net/skrln/zSjgL/
The svg code of my logo:
<svg width="190" height="121">
<mask id="cutouttext">
<rect width="190" height="121" x="0" y="0" fill="white" />
<path id="number-two" d="M75.3,56.1c7.3-3,14.2-12.5,14.2-24c0-17.7-15.1-32.1-36.8-32.1H0v121.5h52.4c30,0,43.4-16.5,43.4-36.8
C95.8,72.3,87,59.8,75.3,56.1z M66.5,94.6h-49V79.7h0.1l27-22.1c3.5-2.8,5.3-6.1,5.3-9c0-4-3.2-7.6-8.4-7.6c-6.4,0-9.1,5.7-10.2,9
l-14.6-3.9c2.9-10.8,11.8-19.1,25.2-19.1c14.4,0,24.5,9.4,24.5,21.5c0,12.4-9,18.1-17.1,23.8l-10.4,7.3h27.6V94.6z" />
<polygon id="filler" points="190,33.9 190,0 101.6,0 101.6,121.5 190,121.5 190,87.6 141.4,87.6 141.4,74.7 177.1,74.7 177.1,46.6
141.4,46.6 141.4,33.9 " />
</mask>
<rect width="190" height="121" x="0" y="0" fill="white" mask="url(#cutouttext)" />
</svg>
The result so far:
Issue:
The mask isn't behaving the way I want to; I want the inner parts of the "B" and "E" to mask out the gray underlying div so you can see the background image like the image below:
I'm having trouble knowing what part of the logo is the and which one is the . Also I can't seem to figure out the logic behind the <mask> in the SVG.
There's nothing wrong with your SVG. You placed it on a grey background, so the bits that are masked out are grey.
What you want to do is remove the grey background from below the SVG image. There may be neater ways of doing this, but one approach is to use a table layout with the logo in one cell and the grey background in another.
Here's a JSFiddle link
HTML
<div class="gray">
<svg width="190" height="121">
<mask id="cutouttext">
<rect width="190" height="121" x="0" y="0" fill="white" />
<path d="M75.3,56.1c7.3-3,14.2-12.5,14.2-24c0-17.7-15.1-32.1-36.8-32.1H0v121.5h52.4c30,0,43.4-16.5,43.4-36.8
C95.8,72.3,87,59.8,75.3,56.1z M66.5,94.6h-49V79.7h0.1l27-22.1c3.5-2.8,5.3-6.1,5.3-9c0-4-3.2-7.6-8.4-7.6c-6.4,0-9.1,5.7-10.2,9
l-14.6-3.9c2.9-10.8,11.8-19.1,25.2-19.1c14.4,0,24.5,9.4,24.5,21.5c0,12.4-9,18.1-17.1,23.8l-10.4,7.3h27.6V94.6z" />
<polygon points="190,33.9 190,0 101.6,0 101.6,121.5 190,121.5 190,87.6 141.4,87.6 141.4,74.7 177.1,74.7 177.1,46.6
141.4,46.6 141.4,33.9 " />
</mask>
<rect width="190" height="121" x="0" y="0" fill="white" mask="url(#cutouttext)" />
</svg>
<div></div>
</div>
CSS
.body {
background: #550000 url('http://sciencelakes.com/data_images/out/7/8788677-red-background-wallpaper.jpg');
display: block;
height: 500px;
margin: 0;
}
.gray {
display:table-row;
width:100%;
height:121px;
}
.gray div, .gray svg {
display:table-cell;
}
.gray div {
background:gray;
width:100%;
}

SVG: dynamic size based on text, merging objects

<div style="float: left; padding: 10px; border: 1px solid;
background: #ccc">random text</div>
Is there a way to achieve something like this in SVG? I mean to have a rectangle and a text and:
a) rectangle's width and height are dynamic, so when I change the text, the rectangle adjust its size
b) when I move the rectangle, the text goes with it
And would it be easier to achieve something like this in <canvas>?
EDIT:
<defs>
<text id="text1" x="90" y="100" style="text-anchor:start;font-size:30px;">
THIS IS MY HEADER</text>
</defs>
<filter x="0" y="0" width="1" height="1" id="background">
<feFlood flood-color="gray"/>
<feComposite in="SourceGraphic"/>
</filter>
<use xlink:href="#text1" fill="black" filter="url(#background)"/>
Erik Dahlström proposed something like this. How to put padding to the background, how to add eg. shadow or border to the rectangle? And, this doesn't work in IE9, so I cannot accept it. I could just use <foreignObject> if there was a support for it in IE.
And I just figured out the answer for b) point of my question. You have to put both elements in the group:
<g>
<rect x="0" y="0" width="100" height="100" fill="red"></rect>
<text x="50" y="50" font-size="14" fill="blue" text-anchor="middle">Hello</text>
</g>
And then you can move the group using transform param:
<g transform="translate(x, y)">
Seems to work correct in every browser.
You can use JavaScript to adjust the box:
<svg xmlns="http:/www.w3.org/2000/svg" onload="init()" height="100" width="200">
<style type="text/css">
rect {
stroke:black;
stroke-width:1;
fill:#ccc;
}
</style>
<script type="text/javascript">
var text, rect
var padding = 10
function init() {
text = document.getElementsByTagName("text")[0]
rect = document.getElementsByTagName("rect")[0]
adjustRect()
}
function adjustRect() {
var bbox = text.getBBox()
rect.setAttribute("x",bbox.x - padding)
rect.setAttribute("y",bbox.y - padding )
rect.setAttribute("width",bbox.width + 2*padding)
rect.setAttribute("height",bbox.height + 2*padding)
}
</script>
<g>
<rect x="0" y="0" width="100" height="100" fill="red"></rect>
<text x="50" y="50" font-size="14" fill="blue" text-anchor="middle">Hello</text>
</g>
</svg>
<div>
<button onclick="text.textContent='Goodbye';adjustRect()">change text</button>
</div>
Use an svg filter to draw the background, that will adapt to the size and position of the text. See this answer for a full example.

Background image fills Raphael SVG to Canvas via canvg are black

I have found the info on converting a raphael SVG into a canvas element here very helpful. But I'm a little stuck - I have a Raphael SVG drawn (it's a little ugly, sorry, but it works), and I can almost recreate it on canvas via canvg, except my fill patterns are all black. Is there something wrong in the SVG code rendered?
Here is an example of the svg code (innerHTML) of my raphael drawing:
<svg height="530" version="1.1" width="530" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="overflow-x: hidden; overflow-y: hidden; position: relative; "><desc>Created with Raphaël 2.0.0</desc><defs><pattern id="BDC4C7DB-1FF9-4BE5-B868-C7B68C6A7B8B" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1" patternTransform="matrix(1,0,0,1,0,0) translate(535.9612108001184,76)"><image x="0" y="0" href="assets/img/crush_gloss/coral_bell_gloss.jpg"></image></pattern><pattern id="75CC740F-C521-4E46-BE6F-2CE15E4CD6D4" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1" patternTransform="matrix(1,0,0,1,0,0) translate(-31.03878919988169,426)"><image x="0" y="0" href="assets/img/crush_gloss/coral_bell_gloss.jpg"></image></pattern><pattern id="70CBF480-046A-4F7D-8B41-FD642EC8109B" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1" patternTransform="matrix(1,0,0,1,0,0) translate(265.9612108001183,76)"><image x="0" y="0" href="assets/img/crush_gloss/habenero_gloss.jpg"></image></pattern><pattern id="146B2DC3-E4B5-4959-BFCD-6A6CF69E3300" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1" patternTransform="matrix(1,0,0,1,0,0) translate(238.96121080011827,26)"><image x="0" y="0" href="assets/img/crush_gloss/coral_bell_gloss.jpg"></image></pattern> ... AND ON ... </defs></svg>
I am using the following to try to recreate my SVG in canvas:
innerSVG=document.getElementById('app_display').innerHTML;
//alert (innerSVG);
// load svg snippet in the canvas
canvg('canv', innerSVG);
My patterns draw fine, my background fill color is fine, it's just the image fill on the patterns I've drawn that's not okay; they're always black. I have tried referencing them by full url, relative, it makes no difference. There is no base meta tag on this page. Thoughts on where I'm wrong?
Try replacing your href with xlink:href
<image x="0" y="0" xlink:href="assets/img/crush_gloss/coral_bell_gloss.jpg"></image>
Or...
canvg('canv', innerSVG.replace("href","xlink:href"));

Consistently change background colour upon hovering over an SVG link

I decided to play around re-making a nav menu in SVG. It looks quite a bit like this site's nav actually, so nothing much to imagine.
I'm drawing boxes with SVG and then placing text over them, enclosing them both in a link. By attaching a css class to the box, I can set a :hover attritbute, so I can change the background colour when the user hovers over it. The problem is, when the user hovers over the text the color change is reversed, even though the link still works.
How can I make the box change colour as well?
The code looks like this:
<svg width="640px" height="40px"
xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(60 20) ">
<a xlink:href="http://www.apple.com">
<rect width="100" height="40" x="-50" y="-20" rx="5" class="svg_nav" />
<text class= "nav_text" text-anchor="middle" dominant-baseline="mathematical">Home</text>
</a>
</g>
</svg>
What do your style rules look like?
Something like the following should work fine:
<svg width="640px" height="40px"
xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(60 20) ">
<a xlink:href="http://www.apple.com">
<rect width="100" height="40" x="-50" y="-20" rx="5" class="svg_nav" />
<text class= "nav_text" text-anchor="middle" dominant-baseline="mathematical">Home</text>
</a>
</g>
<g transform="translate(166 20) ">
<a xlink:href="http://www.apple.com">
<rect width="100" height="40" x="-50" y="-20" rx="5" class="svg_nav" />
<text class= "nav_text" text-anchor="middle" dominant-baseline="mathematical">Home</text>
</a>
</g>
<style>
g:hover .svg_nav { fill: blue }
g:hover .nav_text { fill: red }
.svg_nav { fill: yellow }
.nav_text { fill: black }
</style>
</svg>

Resources