I would like to target an <a> tag's ID inside an inline SVG that is being used as a responsive image map. I don't need to manipulate the SVG, just launch a modal with fancybox by that ID if someone clicks on that <a href...>. (launch an iframe of a local page in this case)
I have read a dozen threads related to this and understand there is a namespace issue but I'm a JS noob and cant quite put it together - thank you for taking a look!
I did try the $('a[xlink\:href=#shows]’) but no joy.
<div id="inline-svg">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1280" preserveAspectRatio="xMidYMin slice" width="100%" height="100%">
<a xlink:href="http://www.facebook.com/" xlink:title="Facebook" xlink:show="new" id="facebook">
<rect x="1102" y="392” width="102" height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="http://twitter.com/" xlink:title="Twitter" xlink:show="new" id="twitter">
<rect x="1102" y="520" width="102" height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="#" xlink:title="Mailing List" id=“mlist">
<rect x="1215" y="392" width=“102” height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<a xlink:href="shows.html" xlink:title=“Shows” id="shows" >
<rect x="1215" y="520” width=“102” height="104" style="fill:#ec2024;opacity:0.5”/>
</a>
<rect width="1920" height="1280" style="fill:none"/>
</svg>
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#shows”).fancybox({
maxWidth : 400,
maxHeight : 300,
type : 'iframe',
});
});
</script>
changing:
$("#shows”).
to:
$("#shows").
Should work fine.
Related
I'm trying to display a React component inside of an SVG. I used the foreignObject component to display my React object (ToolbarItem) inside of the SVG. However, nothing is displayed. What I did wrong?
Thanks for your help
<svg xmlns="http://www.w3.org/2000/svg" width="222.002" height="119.151" viewBox="0 0 222.002 119.151">
<g id="Margin" transform="translate(-51 -59)">
<path id="Soustraction_10" data-name="Soustraction 10" d="M10914,6398.1h0l-39-38.132v-41.828l39-38.139Z" transform="translate(-10641 -6220.475)" fill="#313c57">
<foreignObject x="40" y="40" width="100" height="100">
<ToolbarItem propKey="marginTop" type='draggableNumber' max={maxTop} />
</foreignObject>
</path>
</g>
</svg>
You can add a body tag
<foreignObject x="40" y="40" width="100" height="100">
<body>
<ToolbarItem propKey="marginTop" type='draggableNumber' max={maxTop} />
</body>
</foreignObject>
EDIT: the above works but generates a warning message.
Do the following instead :
<foreignObject x="40" y="40" width="100" height="100">
<div data-xmlns="http://www.w3.org/1999/xhtml">
<ToolbarItem propKey="marginTop" type='draggableNumber' max={maxTop} />
</div>
</foreignObject>
I have an HTML file, that has a link to export all the <svg> inside to one .SVG. That's perfect, it's what I need and the community helped me a lot.
Now I have a problem that all the SVG inside the file, are clogged on top of each other.
I need them to keep the same 'display' they have on the webpage. I tried using internal, inline and external style... But nothing worked.
The X and Y I have in the <svg> is executed when I open the .SVG file in any program, but it doesn't affect anything on the HTML document.
I'm using the svg-converter.js to get all the .svg inside the <img> and convert to <svg>.
For some reason, inside that JS, something don't let me group all the <svg> inside another <svg>, only inside <div>. I have no idea if that is somehow causing the problem of the style not being exported.
Here is the working link.
Any help will be much appreciated.
Ps: I'd love to know why my question is downvoted.
You need to use x and y attributes to arrange your inner <svg> elements inside your root <svg> element.
Something like this (I've replaced the SVG contents with circles for brevity):
<svg xmlns="http://www.w3.org/3000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 1224 1224">
<svg x="0" y="0" width="50%" height="50%" viewBox="0 0 612 612">
<circle fill="#7AB344" cx="306" cy="306" r="250"/>
</svg>
<svg x="50%" y="0" width="50%" height="50%" viewBox="0 0 612 612">
<circle fill="#8DD4F0" cx="306" cy="306" r="250"/>
</svg>
<svg x="0" y="50%" width="50%" height="50%" viewBox="0 0 612 612">
<circle fill="orange" cx="306" cy="306" r="250"/>
</svg>
<svg x="50%" y="50%" width="50%" height="50%" viewBox="0 0 612 612">
<circle fill="rebeccapurple" cx="306" cy="306" r="250"/>
</svg>
</svg>
THIS IS THE FINAL WORKING CODE:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/3000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://brand.express/projects/teste/svg-converter.js"></script>
</head>
<body>
<main id="content">
<div id="mySVG" style="width:100%;padding:0;margin:0;">
<img src='img/leafers-sapling.svg' class='svg-convert' x="0" y="0" width="286px">
<img src='img/aqualine-sapling.svg' class='svg-convert' x="286px" y="0" width="286px">
<img src='img/leafers-sapling.svg' class='svg-convert' x="572px" y="0" width="286px">
<img src='img/aqualine-sapling.svg' class='svg-convert' x="858px" y="0" width="286px">
</div>
</main>
<script>
//transforma os .svg para <svg>
jQuery(document).ready(function($) {
$('.svg-convert').svgConvert({
onComplete: function() {
exportSVG(document.getElementById('mySVG'));
},
svgCleanupAttr: []
});
});
</script>
<script>
var exportSVG = function(divContainer) {
var svgContainer = document.createElementNS("http://www.w3.org/1999/xhtml", "svg");
svgContainer.setAttribute('width','1200px');
$('#mySVG').find("svg").clone().appendTo(svgContainer);
var svgData = svgContainer.outerHTML;
var a = document.createElement('a');
a.href = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
a.download = 'finalSVG.svg';
a.innerHTML = 'download the .SVG file';
document.body.appendChild(a);
};
</script>
</body>
</html>
<svg width="33.5cm" height="57.5cm" style="border:1px solid black;">
<svg width="31.8cm" height="54cm" x="1cm" y="2cm" style="border:1px solid black;">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
<!-- Header -->
<svg width="100%" height="5.8cm">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
<!-- Logo -->
<svg width="23.6cm" height="100%">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
</svg>
</svg>
<!-- body -->
<svg width="100%" height="20.6cm" transform="translate(0cm,5.8cm)">
<rect width="100%" height="100%" style="stroke:black; stroke-width:3; fill:none;"/>
</svg>
<!-- Ad -->
<svg width="100%" height="26.8cm">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
</svg>
</svg>
</svg>
i'm working on svg in html and added some nested svg in the webpage. how can I position the child svg contents which are present in a parent svg? the x and y coordinate is not working. and also tried translate but it is not working. I want to give values in cm (I don't know how to do it), but values in px also not working. is there a way to position svgs relative to one another? or if not possible, how can I translate or position it manually?
The code is in sniplet, kindly check it out
You can use x and y attributes to position nested <svg> elements. For example:
<!-- body -->
<svg width="100%" height="20.6cm" x="0" y="5.8cm">
In the example below I have used this method to position the body svg. I also made it red here so it is obvious which one it is.
<svg width="33.5cm" height="57.5cm" style="border:1px solid black;">
<svg width="31.8cm" height="54cm" x="1cm" y="2cm" style="border:1px solid black;">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
<!-- Header -->
<svg width="100%" height="5.8cm">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
<!-- Logo -->
<svg width="23.6cm" height="100%">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
</svg>
</svg>
<!-- body -->
<svg width="100%" height="20.6cm" x="0" y="5.8cm">
<rect width="100%" height="100%" style="stroke:black; stroke-width:3; fill:red;"/>
</svg>
<!-- Ad -->
<svg width="100%" height="26.8cm">
<rect width="100%" height="100%" style="stroke:black; stroke-width:1; fill:none;"/>
</svg>
</svg>
</svg>
Note Be aware that a "cm" in SVG units will almost certainly not correspond to a real-world cm - for example on screen or printed. SVG units like "cm" and "in" are based on a standard CSS DPI of 96 CSS pixels per inch. No attempt is made to match the real DPI of the device that the SVG is being rendered on.
I wish to fit svg text inside a rect. I could use an approach to compare the widths and add line breaks to the text, but it's not tedious.
Is there a more elegant way than this? Maybe by using CSS or d3?
UPDATE:the following code appends foreignObject using d3 but the div is not displayed. (it is there in the code inspecter)
var group = d3.select("#package");
var fo = group.append("foreignObject").attr("x", 15).attr("y", 15).attr("width", 190).attr("height", 90);
fo.append("div").attr("xmlns", "http://www.w3.org/1999/xhtml").attr("style", "width:190px; height:90px; overflow-y:auto").text("Thiggfis the dgdexsgsggs wish to fit insidegssgsgs");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<p id="p"></p>
<svg width="220" height="120" viewBox="0 0 220 120" id="package">
<rect x="10" y="10" width="200" height="100" fill="none" stroke="black"/>
</svg>
A namespace cannot be assigned by attr, it's a side effect of element creation. You need an html div so you need to tell d3 that by calling the element xhtml:div, once you do that, d3 will do the rest.
var group = d3.select("#package");
var fo = group.append("foreignObject").attr("x", 15).attr("y", 15).attr("width", 190).attr("height", 90);
fo.append("xhtml:div").attr("style", "width:190px; height:90px; overflow-y:auto").text("Thiggfis the dgdexsgsggs wish to fit insidegssgsgs");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<p id="p"></p>
<svg width="220" height="120" viewBox="0 0 220 120" id="package">
<rect x="10" y="10" width="200" height="100" fill="none" stroke="black"/>
</svg>
Here's a simple example of a foreignObject used to insert HTML markup into an SVG:
<svg width="220" height="120" viewBox="0 0 220 120">
<rect x="10" y="10" width="200" height="100" fill="none" stroke="black" />
<foreignObject x="15" y="15" width="190" height="90">
<div xmlns="http://www.w3.org/1999/xhtml" style="width:190px; height:90px; overflow-y:auto"><b>This</b> is the <i>text</i> I wish to fit inside <code>rect</code></div>
</foreignObject>
</svg>
In this svg file(KLICK ME) I want to have a more detailed tooltip with more line in it. So I need some kind of linebreak. I tried allready \n, <br> and
with no effect... And I couldn't find anything more on the webs, so I hope some javascript crack may help me :D
Here goes my code:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="440" height="391" onload="init(evt)" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background-color:white;">
<style>
.tooltip{
font-family: Verdana;
fill:white;
}
.tooltip_bg{
fill: black;
opacity: 0.5;
}
</style>
<script type="text/ecmascript">
<![CDATA[
function init(evt){
if ( window.svgDocument == null ){
svgDocument = evt.target.ownerDocument;
}
tooltip = svgDocument.getElementById('tooltip');
tooltip_bg = svgDocument.getElementById('tooltip_bg');
}
function ShowTooltip(evt, mouseovertext){
tooltip.setAttributeNS(null,"x",evt.clientX+11);
tooltip.setAttributeNS(null,"y",evt.clientY+27);
tooltip.firstChild.data = mouseovertext;
tooltip.setAttributeNS(null,"visibility","visible");
length = tooltip.getComputedTextLength();
tooltip_bg.setAttributeNS(null,"width",length+8);
tooltip_bg.setAttributeNS(null,"x",evt.clientX+8);
tooltip_bg.setAttributeNS(null,"y",evt.clientY+11);
tooltip_bg.setAttributeNS(null,"visibility","visibile");
}
function HideTooltip(evt){
tooltip.setAttributeNS(null,"visibility","hidden");
tooltip_bg.setAttributeNS(null,"visibility","hidden");
}
]]>
</script>
<a xlink:href="webseite.html" onmousemove="ShowTooltip(evt, 'Tooltip zu 01')" onmouseout="HideTooltip(evt)">
<rect x="100" y="0" ry="1" width="40" height="50" style="fill:gold;" />
</a>
<a xlink:href="webseite.html" onmousemove="ShowTooltip(evt, 'Tooltip zu 01')" onmouseout="HideTooltip(evt)">
<text x="120" y="25" text-anchor="middle" dominant-baseline="central" font-family="sans-serif">01</text>
</a>
<a xlink:href="webseite.html" onmousemove="ShowTooltip(evt, 'Tooltip zu 02')" onmouseout="HideTooltip(evt)">
<rect x="200" y="0" ry="1" width="40" height="50" style="fill:gold;" />
</a>
<a xlink:href="webseite.html" onmousemove="ShowTooltip(evt, 'Tooltip zu 02')" onmouseout="HideTooltip(evt)">
<text x="220" y="25" text-anchor="middle" dominant-baseline="central" font-family="sans-serif">02</text>
</a>
<rect class="tooltip_bg" id="tooltip_bg" x="0" y="0" ry="2" width="55" height="21" visibility="hidden"/>
<text class="tooltip" id="tooltip" x="0" y="0" visibility="hidden">Tooltip</text>
</svg>
Why not use native toolips which should support this?
<a xlink:href="webseite.html">
<title>Toolip
zu b</title>
<rect x="100" y="0" ry="1" width="40" height="50" style="fill:gold;" />
</a>
Otherwise you'll need to create multiple <text> elements or embed <tspan> elements in the <text> elements so you can assign dy offsets to simulate line breaks. I.e. you'll have to code multiple line support yourself from scratch.
You'll need to generate something like
<text x="10" y="20">Toolip<tspan x="10" dy="1em">zu b</tspan></text>
where the x and y values vary depending on where your object is.
Or. if you don't care about IE support use a foreignObject element for the tooltips and rely on html's text formatting capability to insert line breaks automatically.
You can use an absolute div with a higher z-index as a tooltip if needs be. This supports any sort of html formatting inside it, as it is just a div tag.
Here is a fiddle to demonstrate: http://jsfiddle.net/pbja2ju6/