Is there any way to make an SVG object clickable? - javascript

I'm working with the SVG that can be viewed here: http://n1t2.info/
I would just post the SVG, but because of the street maps layer the file is extremely large. However, you can see if you click the link that it's a map divided into 18 different svg paths, with a number of different colors shading them. My goal with this map is to make each of the 18 different sections clickable, or be able to give them an <a href="example.com">. Is this possible with SVGs at all?
edit: A comment suggested a show the way that I'm constructing the SVG file. You can see my method for that here.

IMO, the best solution is the SVG <a> element.
<svg width="200" height="200" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<a xlink:href="http://stackoverflow.com/questions/15532371/do-svg-docs-support-custom-data-attributes">
<path d="M 100 100 L 300 100 L 200 300 z" fill="orange" stroke="black" stroke-width="3"></path>
</a>
</svg>

You can handle it pretty easily by adding a data attribute to each <path> element and then handle it via jquery or just javascript.
First, add something like data-url="http://your-url.com" to the
<path> element. Example: <path data-url="http://your-url.com">.
Add jquery library just before the closing of your </body> tag, and the script in step #3 just like:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>
//your script
</script>
</body>
</html>
instead of //your script you'll paste this one:
$(document).ready(function(){
$('path').on('click', function(e){
e.preventDefault();
var url = $(this).data('url');
console.log('Moving to:', url);
window.open(url, '_blank');
});
});
Test it: http://jsfiddle.net/jpvu852d/

A search on google turned up this jQuery plugin for decorating image maps that may help you achieve your goal:
http://www.outsharked.com/imagemapster/default.aspx?what.html

Related

Pupeteer generate non tagged SVG path elements in PDF

I generate a PDF from HTML page sent to pupeteer in small nodeJs app. The generation is ok.
My goal is to make that PDF pass the WCAG2 "PAC 2021" testing tool (https://pdfua.foundation/en/pdf-accessibility-checker-pac).
So I had tagged every elements of my html page from WCAG2 specifications.
But it seems that the <path> tag of each SVG raise an error as "non tagged item". As pupeteer generate SVG for many elements (like borders) and also as I want to print highcharts graph, it is a real problem that makes crash the validation of the tool.
So I tried to tag every path object in my HTML page and I also tagged the parent SVG like this :
<svg focusable="false" role="img" aria-describedby="desc_svg" aria-labelledby="title_svg" width="335" height="335" viewBox="0 0 335 335" fill="none" xmlns="http://www.w3.org/2000/svg">
<title id="title_svg">The title of the SVG</title>
<desc id="desc_svg">The description of the SVG</desc>
<path aria-hidden="true" role="presentation" fill-rule="evenodd" clip-rule="evenodd" d="M131" fill="#2E404F"/>
</svg>
I tried to make the SVG compliant by folowing these guidelines :
https://css-tricks.com/accessible-svgs/#aa-2-inline-svg
https://a11y-guidelines.orange.com/en/articles/accessible-svg/
https://www.smashingmagazine.com/2021/05/accessible-svg-patterns-comparison/
Nothing seems to work, accessibility error is still poping on these tagged items.
Is anybody faced the same problem ?

How can I change an SVG color without using an ID in the SVG file itself?

Newbie to working with SVGs and I've run into a problem. Basically I'm using the Noun Project API pro version ( https://api.thenounproject.com/ ) to scrape icons as SVGs. Right now, I save the SVGs in a local folder. I want to be able to change the color of the icon (right now they download as black, and I want to change the color). I am loading the SVGs via the tag with a reference to the folder where the SVGs are being saved. I know it's fairly simple to change the color using vanilla JS (using document.getElementById('svgObject').contentDocument, and then accessing the inner document using a unique id). The problem is that the SVGs I save don't have any ID, and I don't know how to give them an ID. Right now, I'm looping through the folder and displaying the folder contents in a webpage. That's all working fine, but I can't manage to figure out how to change the color.
Basically, I just want all the icons in the folder to be set to a different color (for example, they could all be set to "red." They don't need to each have a different color). How do I do that without specifying the actual ID (since the SVG doesn't include an ID upon download), or else how do I add an ID to the SVG tag itself?
Assuming you have a bunch of svgs on your page and you'd like to change the color of each to the same color, you could do the following:
function changeSvgColors() {
const svgs = document.getElementsByTagName('svg')
for (let i = 0; i < svgs.length; i++) {
svgs[i].setAttribute('fill', 'red')
}
}
This will loop through every svg on your page and set their fill attribute to red.
Essentially, this is equivalent to doing this:
<svg viewBox="0 0 512 512" fill="red">
...
</svg>
Here's a quick demo:
JSFiddle
Alternatively, if you're using something like the img tag to load your svgs onto your page, using object instead would let you do the same thing as above.
Assuming your html looks like the following:
<div>
<object
data="http://localhost:5000/image.svg"
type="image/svg+xml"
></object>
</div>
Then,
function changeSvgColors() {
const objects = document.getElementsByTagName('object')
for (let i = 0; i < objects.length; i++) {
const object = objects[i]
const svg = object.contentDocument.rootElement
svg.setAttribute('fill', 'red')
}
}
One option would be using the svg as an image (or as an object if you prefer) and filters to change the color.
#theImage{filter: invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);}
<img id="theImage" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg" >
Please read this article: Solved with CSS! Colorizing SVG Backgrounds
Yet another option is using the svg as a mask. Keep in mind that the support for mask is not that good.
#theDiv{
display: inline-block;
width:300px;
height:134px;
-webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg);
mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg);
mask-size: cover;
background:red;
}
<div id="theDiv"></div>
But the best option would be to use the svg inline. You may save all your icons in a root svg element with width="0"; height="0"; position="absolute". Next you can use the icons with <use> and you change the color using the fill attribute <use fill="red" xlink:href="..... or styling it in CSS
You can give the SVGs a class instead of an id & set the color using javascript's getElementsByClassName
This Mozilla article explains:
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
Your best shot in achiveing this is to make use of the fill attibute for svg elements. Now, you can work this out two ways
Method 1:
Using img tag like this <img src="your_file.svg" />. In this case, you will need to edit the file directly, and that's it, it should reflect everywhere you reference the svg.
Method 2:
You can use svg as inline like below. The advantage in this approach is that if you have varying instance of the same svg, then this is the way to go. On the other side, if your svg stays same throughout the app, this goes against the DRY principle.
svg {
max-width: 200px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M25,7l28,36l40-18l-36,25l19,44l-27-37l-41,17l36-26z" fill="#cfc"/>
<ellipse cx="50" cy="50" rx="32" ry="30" stroke="#fc0" fill="none" stroke-width="11"/>
<path d="M63,2l-7,43l42,17l-45-6l-16,42l7,-45l-42-16l45,6z" fill="#3cc"/>
</svg>
If you don't mind having the svg all one color, you could set the fill attribute of the svg to currentcolor. Then it will take on the color of the element that it is in.
#span1 {
color: red;
}
#span2 {
color: blue;
}
#span3 {
color: green;
}
<body>
<span id=span1>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
<span id=span2>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
<span id=span3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
</body>

How to extract data <d> in svg through javascript

I wrote an icon component through reactjs to parse the svg files. I use storybook to show my icon component. Now I need help for writing a command line to parse the svg file to the component. I need to script the element in in a svg file and I have no idea how to achieve it.
I am planning to write it in javascript. And here is one example of my svg files.
<svg viewBox="0 0 1024 1024" p-id="3378" width="200" height="200">
<path d="..." p-id="3379"></path>
</svg>
May anyone gives me some ideas on how to achieve it. I am bad at extracting data from a file.
For the specific question from the title, use the following JS code:
document.querySelector("object")
.contentDocument.querySelectorAll("path[path-id='3379']")[0].getAttribute("d")
The SVG should be referenced using the object element (replace width/height attribute content with proper values):
<object
type="image/svg+xml"
data="./logo.svg"
width="480"
height="240"
></object>
It is assumed that there is a single object element in your html. Otherwise tag them with an id attribute and use #<the_id_goes_here> in the first selector:
document.querySelector("#<the_id_goes_here>")
.contentDocument.querySelectorAll("path[path-id='3379']")[0].getAttribute("d")

accessing inline SVG elements with javascript

I'm playing around with SVG and I've hit a wall.
what im trying to do it when you hover over on svg element it will cause another to appear.
my idea was using javascript to add and remove a "hidden" class when you hover, but its not working, it works on none SVG elements but I can't see why it's not working here.
<svg xmlns:cc="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
width="400px"
height="400px"
viewBox="0 150 960 900">
<path id="loc36" class="maploc" d="m 352.28954,738.20354 0,140.66609 85.8653,0 0,-140.41399 z"/>
<path id="info36" class="infopanel " d="m 306.42857,896.64787 0,157.85713 539.28572,0 0,-158.57141 z"/>
</svg>
Javascript
$("#loc36").hover(function(){
$('#info36').removeClass('hidden');
},function(){
$('#info36').addClass('hidden');
});
https://jsfiddle.net/atprsteq/
Its works on none SVG elements, like this example
http://jsfiddle.net/EzfwV/210/
Am I just missing something simple here?
Am I just missing something simple here?
Yes.
You forgot to include jQuery!
Select jQuery from the "Frameworks & Extensions" menu.

outerHtml returns undefined for SVG elements in IE

Here is my code
<svg id="a" height="210" width="400">
<path id="b" d="M150 0 L75 200 L225 200 Z" />
</svg>
i have trigger mouse move event on b
$("#b").hover(function() {
alert($(this)[0].outerHTML);
});
this was working in chrome but not working in IE how can i solve this..
please find the JSFiddle link : http://jsfiddle.net/r8v70Lnk/
alert box will show only in chrome but not in IE..
Dont know if it is a solution for you but i usually do it like:
new XMLSerializer().serializeToString(document.querySelector('#b'))
If you want to parse the string again and insert the node in your document:
new DOMParser().parseFromString(svgString, "image/svg+xml")

Categories

Resources