Draw Svg to canvas including images embedded in svg - javascript
<html
><svg width="960" height="500" id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg"><g class="linz"><line class="bluelink" x1="480" y1="250" x2="334.8434764825239" y2="275.78849826638145"></line><rect x="397.42173824126195" y="252.89424913319073" width="20" height="20" style="fill: black; stroke: skyblue;"></rect><text class="link-label" font-family="Arial, Helvetica, sans-serif" fill="white" dy=".35em" text-anchor="middle" x="407.42173824126195" y="262.8942491331907">101</text></g><g class="linz"><line class="bluelink" x1="480" y1="250" x2="619.1894601470176" y2="200.9990683994202"></line><rect x="539.5947300735088" y="215.4995341997101" width="20" height="20" style="fill: black; stroke: skyblue;"></rect><text class="link-label" font-family="Arial, Helvetica, sans-serif" fill="white" dy=".35em" text-anchor="middle" x="549.5947300735088" y="225.4995341997101">2</text></g><g class="linz"><line class="bluelink" x1="480" y1="250" x2="434.983433226373" y2="390.53065260546134"></line><rect x="447.4917166131865" y="310.26532630273067" width="20" height="20" style="fill: black; stroke: skyblue;"></rect><text class="link-label" font-family="Arial, Helvetica, sans-serif" fill="white" dy=".35em" text-anchor="middle" x="457.4917166131865" y="320.26532630273067">2</text></g><g class="linz"><line class="bluelink" x1="480" y1="250" x2="585.5868329731418" y2="353.5574331993295"></line><rect x="522.7934164865709" y="291.7787165996648" width="20" height="20" style="fill: black; stroke: skyblue;"></rect><text class="link-label" font-family="Arial, Helvetica, sans-serif" fill="white" dy=".35em" text-anchor="middle" x="532.7934164865709" y="301.7787165996648">119</text></g><g class="linz"><line class="bluelink" x1="480" y1="250" x2="499.47384868808143" y2="103.87072365281172"></line><rect x="479.73692434404074" y="166.93536182640585" width="20" height="20" style="fill: black; stroke: skyblue;"></rect><text class="link-label" font-family="Arial, Helvetica, sans-serif" fill="white" dy=".35em" text-anchor="middle" x="489.73692434404074" y="176.93536182640585">2</text></g><g class="linz"><line class="bluelink" x1="480" y1="250" x2="373.73145030208514" y2="147.4006224017257"></line><rect x="416.86572515104257" y="188.70031120086287" width="20" height="20" style="fill: black; stroke: skyblue;"></rect><text class="link-label" font-family="Arial, Helvetica, sans-serif" fill="white" dy=".35em" text-anchor="middle" x="426.86572515104257" y="198.70031120086287">5</text></g><g class="node" transform="translate(334.8434764825239,275.78849826638145)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/call.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">111</text></g><g class="node" transform="translate(619.1894601470176,200.9990683994202)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/call.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">999</text></g><g class="node" transform="translate(434.983433226373,390.53065260546134)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/call.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">222</text></g><g class="node" transform="translate(585.5868329731418,353.5574331993295)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/call.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">XXX</text></g><g class="node" transform="translate(499.47384868808143,103.87072365281172)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/call.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">444</text></g><g class="node" transform="translate(373.73145030208514,147.4006224017257)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/call.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">333</text></g><g class="node" transform="translate(480,250)"><circle r="10.392304845413264" style="fill: white;"></circle><image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="images/target.png" x="-17" y="-17" height="30" width="30"></image><text dy="2.6em">Main</text></g></svg>
On Coverting to Canvas using given code
var svgText = document.getElementById("myViewer").outerHTML;
var myCanvas = document.getElementById("canvas");
var ctxt = myCanvas.getContext("2d");
function drawInlineSVG(ctx, rawSVG, callback) {
var svg = new Blob([rawSVG], {type:"image/svg+xml;charset=utf-8"}),
domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(svg),
img = new Image;
img.onload = function () {
ctx.drawImage(this, 0, 0);
domURL.revokeObjectURL(url);
callback(this);
};
img.src = url;
}
// usage:
drawInlineSVG(ctxt, svgText, function() {
console.log(canvas.toDataURL()); // -> PNG
alert("see console for output...");
});
no links or images are shown on canvas though images and links are shown on svg.
How to do it and add jpg/svg/print/pdf functionality?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/akhilsahu/saveSvgAsPngJpgSvg/master/svg.js"></script>
saveSvAsPngJpgSvg.js
https://github.com/akhilsahu/saveSvgAsPngJpgSvg
It is too easy to use.
Easy functions can be called to do so.
svgAsPngUri(document.getElementById(svgid), {}, function(uri)
{
document.querySelector('#png-container').innerHTML = '<img id="getimg" style="display:none" src="'+uri+'"/>';
var sampleImage = document.getElementById("getimg"),
canvas = convertImageToCanvas(sampleImage);
// Actions
document.getElementById("canvasHolder").appendChild(canvas);
});
The canvas is added.You can't see as its hidden.
Fiddle hereclick
Here are some tests:
http://jsfiddle.net/MxHPq/140/
Looks like only images that are embedded in the SVG as Data URIs can be drawn on the canvas (the red dot in this example):
<svg id="example1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="100" >
...
<image id="embedded" x="80" y="70" width="20" height="20" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
</svg>
Here is an online tool which converts images to Data URIs:
http://duri.me/
Related
text is going out of <svg><rect> box once in 1000x times but on safari browser always reproduce this bug
Im trying to fix this bug, and I have tried alot things but nothing help, if I give value of x='23%' like <text id="badgeText" x = "23% ... I can fix bug on safari but than bug start repodruce everytime on other browsers(mozila,chrome etc...), anyhow the bug is reproducing once in many times on other browsers ... bug image <div class="CoveoShowIfFieldValue" data-field="#isRecommended" data-field-value="True"> <svg height="25px" style="overflow:visible!important;"> <g id="recommendedBadge" style="object-fit:contain!important;"> <rect x="0" y="0" rx="15px" ry="15px"/> <text id="badgeText" y="66%" font-family="Metric" text-anchor="middle" class="CoveoText" data-value="RECOMMENDED" style="text-transform: uppercase;"></text> <g class="tooltip" transform="translate(21,62)"> <rect x="-6%" width="450" y="-35" height="25" rx="5px" ry="5px"/> <text y="-31" dy="1em" font-family="Metric" text-anchor="middle" font-weight="100" class="CoveoText" data-value="RecommendedTooltip"></text> </g> </g> </svg> </div>
It’s not a bug: You need to add some width related properties like width or a viewBox. Otherwise a browser can’t tell how to render a relative unit within a svg element. Some browsers might be more forgiving by guessing or setting default width values as fallbacks. (Currently most firefox and chromium based browsers use 300px as a fallback). <style> svg { border: 1px solid red; height: 25px; } text { fill: #fff; } </style> <h2>Use viewBox</h2> <svg viewBox="0 0 450 25" style="overflow:visible!important;"> <g id="recommendedBadge"> <rect x="0" y="0" rx="15" ry="15" width="100%" height="25" /> <text id="badgeText" x="50%" y="50%" dy="2" dominant-baseline="middle" font-family="Metric" text-anchor="middle" class="CoveoText" data-value="RECOMMENDED" style="text-transform: uppercase;"> Badge Text </text> <g class="tooltip" transform="translate(0 25)"> <rect x="0" y="0" width="100%" height="100%" rx="5" ry="5" fill="red" /> <text x="50%" y="50%" dy="5" font-family="Metric" text-anchor="middle" font-weight="100" class="CoveoText" data-value="RecommendedTooltip">tooltip</text> </g> </g> </svg> <br><br><br> <h2>Use width</h2> <svg height="25" width="100%" style="overflow:visible!important;"> <g id="recommendedBadge"> <rect x="0" y="0" rx="15" ry="15" width="100%" height="25" /> <text id="badgeText" x="50%" y="50%" dy="2" dominant-baseline="middle" font-family="Metric" text-anchor="middle" class="CoveoText" data-value="RECOMMENDED" style="text-transform: uppercase;"> Badge Text </text> <g class="tooltip" transform="translate(0 25)"> <rect x="0" y="0" width="100%" height="100%" rx="5" ry="5" fill="red" /> <text x="50%" y="50%" dy="5" font-family="Metric" text-anchor="middle" font-weight="100" class="CoveoText" data-value="RecommendedTooltip">tooltip</text> </g> </g> </svg>
SVG masked progress bar
Can someone mastered in SVG help me with creating that simple progress bar where the blue color is moving according to a percentage? I tried but with no luck or can be simpler.
Just for the POC purpose, I have added SVG code directly into the HTML. You can create a path group of vertical bars and put the filling object right behind that group. I have added simple animation to show the working animation. Please let me know if I have missed anything. function loadAnim() { window.onload = function () { let xval = 100; setInterval(() => { if (xval <= 0) { return 0; } else { document.getElementById('progress').setAttribute('x', '0'); } }, 1000); }; } loadAnim(); rect#progress { transition: all 0.9s linear; } <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 79 20" style="enable-background: new 0 0 79 20" xml:space="preserve" > <rect x="0" y="0" style="fill: #adadad" width="79" height="20" /> <rect id="progress" x="-79" y="0" style="fill: #0077d8" width="79" height="20" /> <g> <path style="fill: #ffffff" d="M15,18.5v-17C15,0.7,15.7,0,16.5,0h-4C13.3,0,14,0.7,14,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C15.7,20,15,19.3,15,18.5z" /> <path style="fill: #ffffff" d="M20,18.5v-17C20,0.7,20.7,0,21.5,0h-4C18.3,0,19,0.7,19,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C20.7,20,20,19.3,20,18.5z" /> <path style="fill: #ffffff" d="M35,18.5v-17C35,0.7,35.7,0,36.5,0h-4C33.3,0,34,0.7,34,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C35.7,20,35,19.3,35,18.5z" /> <path style="fill: #ffffff" d="M25,18.5v-17C25,0.7,25.7,0,26.5,0h-4C23.3,0,24,0.7,24,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C25.7,20,25,19.3,25,18.5z" /> <path style="fill: #ffffff" d="M30,18.5v-17C30,0.7,30.7,0,31.5,0h-4C28.3,0,29,0.7,29,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C30.7,20,30,19.3,30,18.5z" /> <path style="fill: #ffffff" d="M0,18.5V20h1.5C0.7,20,0,19.3,0,18.5z" /> <path style="fill: #ffffff" d="M10,18.5v-17C10,0.7,10.7,0,11.5,0h-4C8.3,0,9,0.7,9,1.5v17C9,19.3,8.3,20,7.5,20h4 C10.7,20,10,19.3,10,18.5z" /> <path style="fill: #ffffff" d="M1.5,0H0v1.5C0,0.7,0.7,0,1.5,0z" /> <path style="fill: #ffffff" d="M5,18.5v-17C5,0.7,5.7,0,6.5,0h-4C3.3,0,4,0.7,4,1.5v17C4,19.3,3.3,20,2.5,20h4 C5.7,20,5,19.3,5,18.5z" /> <path style="fill: #ffffff" d="M65,18.5v-17C65,0.7,65.7,0,66.5,0h-4C63.3,0,64,0.7,64,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C65.7,20,65,19.3,65,18.5z" /> <path style="fill: #ffffff" d="M77.5,20H79v-1.5C79,19.3,78.3,20,77.5,20z" /> <path style="fill: #ffffff" d="M75,18.5v-17C75,0.7,75.7,0,76.5,0h-4C73.3,0,74,0.7,74,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C75.7,20,75,19.3,75,18.5z" /> <path style="fill: #ffffff" d="M70,18.5v-17C70,0.7,70.7,0,71.5,0h-4C68.3,0,69,0.7,69,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C70.7,20,70,19.3,70,18.5z" /> <path style="fill: #ffffff" d="M77.5,0C78.3,0,79,0.7,79,1.5V0H77.5z" /> <path style="fill: #ffffff" d="M50,18.5v-17C50,0.7,50.7,0,51.5,0h-4C48.3,0,49,0.7,49,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C50.7,20,50,19.3,50,18.5z" /> <path style="fill: #ffffff" d="M60,18.5v-17C60,0.7,60.7,0,61.5,0h-4C58.3,0,59,0.7,59,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C60.7,20,60,19.3,60,18.5z" /> <path style="fill: #ffffff" d="M45,18.5v-17C45,0.7,45.7,0,46.5,0h-4C43.3,0,44,0.7,44,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C45.7,20,45,19.3,45,18.5z" /> <path style="fill: #ffffff" d="M40,18.5v-17C40,0.7,40.7,0,41.5,0h-4C38.3,0,39,0.7,39,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C40.7,20,40,19.3,40,18.5z" /> <path style="fill: #ffffff" d="M55,18.5v-17C55,0.7,55.7,0,56.5,0h-4C53.3,0,54,0.7,54,1.5v17c0,0.8-0.7,1.5-1.5,1.5h4 C55.7,20,55,19.3,55,18.5z" /> </g> </svg>
How to insert multiline text in a svg element
As a primer in svg and javascript I've been trying for a while to make this code work with no avail. My problem is that I'm not able to take the text from a text element (class="texts") and put it into another one (MySpeechBoxText1) maintaining it's multiline formatting. Here is my code: <svg xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" width="594mm" height="420mm" id="svg58064" viewBox="0 0 2245.0393 1587.4016"> <style> .bar { fill: #a9a9a9; opacity: 0.6; } </style> <g class="miogruppo"> <rect class="bar" x="50" y="60" width="80" height="120"/> <text class="texts" x="0" y="50" font-family="Verdana" font-size="35" fill="blue" display='none'> <tspan x="20" dy="1.2em">test 1</tspan> <tspan x="20" dy="1.2em">test 1</tspan> </text> </g> <g class="miogruppo"> <rect class="bar" x="180" y="80" width="80" height="170"/> <text class="texts" x="0" y="50" font-family="Verdana" font-size="35" fill="blue" display='none'> <tspan x="20" dy="1.2em">test 2</tspan> <tspan x="20" dy="1.2em">test 2</tspan> </text> </g> <g id="group1" display='none'> <title>Tester 2</title> <path id="test1" d="M15,0 H150 V150 H15 L15,90 L0,90 L15,75 Z15 " style="stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round; stroke-dasharray:none;stroke-miterlimit:4;stroke-opacity:1;fill-opacity:0.5;fill:#ffffff" inkscape:connector-curvature="0"/> <text id="MySpeechBoxText1" x="60" y="60" > </text> </g> <script><![CDATA[ var bars = document.getElementsByClassName('bar'); var texts = document.getElementsByClassName('texts'); var mySpeechBox = document.getElementById("group1"); var MySpeechBoxText1 = document.getElementById("MySpeechBoxText1"); for (var i = 0; i < bars.length; i++) { bars[i].addEventListener('mouseover', mouseOverEffect); bars[i].addEventListener('mouseout', mouseOutEffect); bars[i].addEventListener('mousemove', mousemoveEffect(i)); } for (var i = 0; i < texts.length; i++) { texts[i].addEventListener('mouseover', mouseOverEffect); texts[i].addEventListener('mouseout', mouseOutEffect); texts[i].addEventListener('mousemove', mousemoveEffect(i)); } function mouseOverEffect() { mySpeechBox.style.display='block'; } function mouseOutEffect() { mySpeechBox.style.display='none'; } function mousemoveEffect(a) { return function() { var myX = +bars[a].getAttribute("x"); var myY = +bars[a].getAttribute("y"); var myWidth = +bars[a].getAttribute("width"); var myHeight = +bars[a].getAttribute("height"); var MySumX =myX + myWidth/2; var MySumY =myY + myHeight/2 - 90; mySpeechBox.setAttribute("transform", 'translate(' + MySumX + ',' + MySumY + ')'); //MySpeechBoxText1.style.whiteSpace = "pre"; MySpeechBoxText1.textContent = texts[a].textContent; //here the text should be multiline } } ]]></script> </svg>
Instead of textContent, use innerHTML. const text1 = document.querySelector('.text1'); const text2 = document.querySelector('.text2'); text2.innerHTML = text1.innerHTML; <svg viewBox="0 0 240 80" xmlns="http://www.w3.org/2000/svg"> <style> .small { font: italic 13px sans-serif; } .heavy { font: bold 30px sans-serif; } /* Note that the color of the text is set with the * * fill property, the color property is for HTML only */ .Rrrrr { font: italic 40px serif; fill: red; } </style> <text class="text1" x="0" y="5" font-family="Verdana" font-size="10" fill="blue" > <tspan x="20" dy="1.2em">test 1</tspan> <tspan x="20" dy="1.2em">test 1</tspan> </text> <text x="25" y="25" class="text2"></text> </svg>
SVG Input Field
I'm trying to make one of my SVG text fields accept input from the user when they press on it. Is there any way of doing that? const wrapper = document.getElementById('wrapper'); const text = document.getElementById('Username'); const inputWrapper = document.getElementById('input-wrapper'); const input = document.getElementById('input'); const button = document.getElementById('button'); text.addEventListener('click', () => { text.classList.toggle('hide'); inputWrapper.classList.toggle('hide'); input.focus(); }); button.addEventListener('click', () => { text.classList.toggle('hide'); inputWrapper.classList.toggle('hide'); }); input.addEventListener('change', (e) => { text.innerText = e.target.value; }); .cls-1 { clip-path: url(#clip-Login_page); } .cls-2 { opacity: 0.67; fill: url(#pattern); } .cls-3 { fill: #d9d9d9; } .cls-3, .cls-5 { stroke: #0d0d0d; } .cls-4 { fill: url(#pattern-2); } .cls-5 { fill: #f2f2f2; } .cls-6, .cls-7 { fill: #707070; font-family: Georgia; } .cls-6 { font-size: 25px; } .cls-7 { font-size: 20px; } .cls-8 { stroke: none; } .cls-9 { fill: none; } .cls-10 { fill: #fff; } .cls-11 { filter: url(#Rectangle_5); } .cls-12 { filter: url(#Amcan_logo); } .cls-13 { filter: url(#Rectangle_2); } .hide { display: none; } <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 375 667"> <defs> <pattern id="pattern" preserveAspectRatio="none" width="100%" height="100%" viewBox="0 0 1920 1080"> <image width="1920" height="1080" xlink:href="img/Amcan.gif"/> </pattern> <filter id="Rectangle_2" x="11" y="178" width="354" height="63" filterUnits="userSpaceOnUse"> <feOffset dy="5" input="SourceAlpha"/> <feGaussianBlur stdDeviation="3" result="blur"/> <feFlood flood-opacity="0.161"/> <feComposite operator="in" in2="blur"/> <feComposite in="SourceGraphic"/> </filter> <pattern id="pattern-2" preserveAspectRatio="none" width="100%" height="100%" viewBox="0 0 593 186"> <image width="593" height="186" xlink:href="img/Amcan_logo.png"/> </pattern> <filter id="Amcan_logo" x="13" y="28" width="349" height="123" filterUnits="userSpaceOnUse"> <feOffset dy="10" input="SourceAlpha"/> <feGaussianBlur stdDeviation="3" result="blur-2"/> <feFlood flood-opacity="0.161"/> <feComposite operator="in" in2="blur-2"/> <feComposite in="SourceGraphic"/> </filter> <filter id="Rectangle_5" x="77" y="369" width="222" height="63" filterUnits="userSpaceOnUse"> <feOffset dy="5" input="SourceAlpha"/> <feGaussianBlur stdDeviation="3" result="blur-3"/> <feFlood flood-opacity="0.161"/> <feComposite operator="in" in2="blur-3"/> <feComposite in="SourceGraphic"/> </filter> <clipPath id="clip-Login_page"> <rect width="375" height="667"/> </clipPath> </defs> <g id="Login_page" data-name="Login page" class="cls-1"> <rect class="cls-10" width="375" height="667"/> <rect id="Amcanerino" class="cls-2" width="510" height="667" transform="translate(-71)"/> <g class="cls-13" transform="matrix(1, 0, 0, 1, 0, 0)"> <g id="Rectangle_2-2" data-name="Rectangle 2" class="cls-3" transform="translate(20 182)"> <rect class="cls-8" width="336" height="45"/> <rect class="cls-9" x="0.5" y="0.5" width="335" height="44"/> </g> </g> <g class="cls-12" transform="matrix(1, 0, 0, 1, 0, 0)"> <rect id="Amcan_logo-2" data-name="Amcan_logo" class="cls-4" width="331" height="104" transform="translate(22 28)"/> </g> <g id="Rectangle_3" data-name="Rectangle 3" class="cls-5" transform="translate(20 250)"> <rect class="cls-8" width="336" height="45"/> <rect class="cls-9" x="0.5" y="0.5" width="335" height="44"/> </g> <g id="Rectangle_4" data-name="Rectangle 4" class="cls-5" transform="translate(20 311)"> <rect class="cls-8" width="336" height="45"/> <rect class="cls-9" x="0.5" y="0.5" width="335" height="44"/> </g> <g class="cls-11" transform="matrix(1, 0, 0, 1, 0, 0)"> <g id="Rectangle_5-2" data-name="Rectangle 5" class="cls-3" transform="translate(86 373)"> <rect class="cls-8" width="204" height="45"/> <rect class="cls-9" x="0.5" y="0.5" width="203" height="44"/> </g> </g> <text id="SUBMIT" class="cls-6" transform="translate(139 405)"><tspan x="0" y="0">SUBMIT</tspan></text> <text id="Login" class="cls-6" transform="translate(156 214)"><tspan x="0" y="0">Login</tspan></text> <div id="wrapper"> <text id="Username" class="cls-7" transform="translate(142 280)"><tspan x="0" y="0">Username</tspan></text> <div id="input-wrapper" class="hide"> <input id="input" type="text" value="Username"/> <button id="button">Submit</button> </div> </div> <text id="Password" class="cls-7" transform="translate(145 341)"><tspan x="0" y="0">Password</tspan></text> </g> </svg> This is the amended code as suggested by Solo.
<tspan> and <text> are not html elements, but svg elements with their own attributes. The property contenteditable doesn't exist on tspan (you can console.log document.querySelector("#myTspan").isContentEditable, it will return undefined. However, it can inherit properties from its parents. So in case of an inline svg in a HTML file, wrapping your svg in an editable element will work in some browsers, but all you texts are then editable. <div contenteditable="true"> <svg> <text id="Username" class="cls-7" transform="translate(142 20)"><tspan x="0" y="0">Username</tspan></text> </svg> </div> In a standalone SVG, you have no way to have contenteditable working since it's part of HTML specification, not that of SVG. You have to go for a script as other answers suggest, but read carefully (since you didn't mentionned at first that it was a standalone svg) : Including JavaScript in SVG
Yes and no, you can't edit the text directly, but you can put an input overtop of it. See the code below: .input-real { background: rgba(255, 255, 255, 0); color: transparent; padding: 0; border: 0 none transparent; line-height: 0; } .input-real:focus { background: rgba(255, 255, 255, 1); color: #333; } .input-real, .input-mimic { font-family: Arial, Helvetica Neue, Helvetica, sans-serif; font-size: 14px; } <svg viewBox="0 0 375 667"> <text id="Username" class="input-mimic" x="50" y="50" alignment-baseline="hanging">Username</text> <foreignObject width="50" height="23" x="50" y="46"> <input id="input" class="input-real" type="text" value="Username"/> </foreignObject> </svg>
use contenteditable on tspan see more here - https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content How does it work? All you have to do is set the contenteditable attribute on nearly any HTML element to make it editable. function toggleEdit() { var text = document.getElementById('Username'); var tspan = text.firstElementChild; tspan.setAttribute('contenteditable', true); } <text id="Username" class="cls-7" transform="translate(142 280)"><tspan x="0" y="0">Username</tspan></text> <div><button onclick="toggleEdit();">Edit input</button></div>
Thank you very much for your help guys! I have found out that I can just use JavaScript 'prompt' form to achieve this. All I had to do was to implement the following: <script> function changeUsername() { document.getElementById('Username').textContent = prompt("Please enter your Username"); } </script> <rect onclick="changeUsername()" class="cls-8" width="336" height="45"/> I completely forgot that the prompt form existed! Again, thank you all :)
No need of jquery or JS, Just add contenteditable="true" to that text element and you're done... <text contenteditable="true" id="Username" class="cls-7" transform="translate(142 280)"><tspan x="0" y="0">Username</tspan></text>
Why isn't my svg's embedded javascript working in an html document?
I have the following code for an svg: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="470px" height="260px" version="1.1" onload="addEvents()" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="baby.jpg" x="0" y="0" height="260px" width="470px"> </image> <g transform="translate(100,50)"> <circle class="circle" id="tip1" cx="20" cy="0" r="10" stroke="" stroke-width="0" fill="rgb(143, 124, 184)" /> <g transform="translate(10,15)"> <polygon class="baby-tip tip1 arrow" points="0,10 10,0, 20,10" style="fill: rgb(143, 124, 184)" /> </g> <rect class="baby-tip tip1" x="0" y="25" height="70" width="220" rx="5" ry="5" style="fill: rgb(143, 124, 184)"/> <text class="baby-tip tip1" x="10" y="45">Here is a whole bunch of text.</text> <text class="baby-tip tip1" x="10" y="60">Clearly this should wrap, but it</text> <text class="baby-tip tip1" x="10" y="75">doesn't. What will we do?</text> </g> <g transform="translate(150,160)"> <circle class="circle" id="tip2" cx="20" cy="0" r="10" stroke="" stroke-width="0" fill="rgb(143, 124, 184)" /> <g transform="translate(10,15)"> <polygon class="baby-tip tip2 arrow" points="0,10 10,0, 20,10" style="fill: rgb(143, 124, 184)" /> </g> <rect class="baby-tip tip2" x="0" y="25" height="70" width="220" rx="5" ry="5" style="fill: rgb(143, 124, 184)"/> <text class="baby-tip tip2" x="10" y="45">Here is a whole bunch of text.</text> <text class="baby-tip tip2" x="10" y="60">Clearly this should wrap, but it</text> <text class="baby-tip tip2" x="10" y="75">doesn't. What will we do?</text> </g> <style> .baby-tip { font-size: 14px; font-family: "MuseoSans100", Arial, Helvetica, sans-serif; fill: white; opacity: 0; } </style> <script> var log = console.info; function addEvents() { var dots = document.getElementsByClassName("circle"); var i = dots.length; while(i--) { toggleTips(dots[i]); } } function closeOtherTips(otherTips) { var l = otherTips.length; while (l--) { otherTips[l].style.opacity = 0; } } function toggleTips(dot, l) { window.dot = dot; dot.addEventListener("click", function() { var className = dot.id; var tips = document.getElementsByClassName(className); var otherTips = document.querySelectorAll('text:not(.' + className + '), rect:not(.' + className + '), polygon:not(.' + className + ')'); var t = tips.length; closeOtherTips(otherTips); while (t--) { tips[t].style.opacity != 0 ? tips[t].style.opacity = 0 : tips[t].style.opacity = 1; } }); } </script> </svg> When I save this content as test.svg, and view it in a browser, it runs beautifully - I should see two purple dots, and when I click each one I get a little tool tip, and only one displays at a time. However, if I create the following html document: <!DOCTYPE html> <html> <body> <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <img class="baby-dot-svg" src="test.svg" /> <img class="baby-dot-bg" src="baby.jpg" /> </body> </html> Two things change: 1) the tooltip / all js functionality is lost - nothing happens when I click on the dots. 2) the link to baby.jpg no longer works - despite baby.jpg and the svg residing in the same directory, the background of the svg is blank. See http://images.agoramedia.com/wte3.0/gcms/web_view_svg_test2.html to view this in action. Why is this breaking?
There are mulitple ways to embed SVG files, but the <img> approach doesn't allow it to be interactive. Try: <object data="test.svg" type="image/svg+xml"> <img src="baby.jpg" /> </object> For more information, see this answer.