Generated SVG image doesn't display - javascript

I'm developing a JavaScript class to show all SVG objects, but when I create the element "image", the browser doesn't display it. Though if I copy the generated code and put it in another document, the image is displayed.
When I searched the image using Firebug's inspector, the object appears but the image is not displayed.
I created the object using appendChild(), setAttribute() and setAttributeNS()
This is the generated code:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="100%" width="100%" >
<image width="50" height="50" xlink:href="logo.png" y="20" x="20" id="d"></image>
</svg>
What I am doing wrong?

The problem were the namespaces. This is the correct form to create images dynamically:
image.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', 'flower.png');
More imformation can be found on MDN's 'Namespaces Crash Course'.

Related

How can we create a proper vector SVG file from HTML canvas using javascript?

What I am trying to achieve:
Generate an SVG file from html canvas using javascript.
What I have tried:
I am generating the image I need using HTML canvas using canvas's CanvasRenderingContext2D and createCanvas().
Writing it to an svg file using canvas's toBuffer() and node's writeFileSync() functions.
The problem:
The generated file is not an actual vector image, but a flattened image in svg format.
This does not allow design softwares to modify the svg.
Something like:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800pt" height="800pt" viewBox="0 0 800 800" version="1.1">
<defs>
<image id="image47" width="800" height="800" xlink:href="data:image/png;base64,iVBORw0KGgoAAAA
//...
</defs>
<g id="surface36">
<use xlink:href="#image47"/>
</g>
</svg>
Is it possible to generate an actual vector (that can be edited in design softwares) from the HTML canvas using any other approach / third party libraries?

Image in png/base64 in svg not displaying in Safari

I embedded an image in svg and tried to plot it in Safari. While it works fine in Firefox, the image doesn't display in Safari. The code is simple and displayed below.
Now the weird thing is that when I put this code in an online test site (http://www.rapidtables.com/web/tools/svg-viewer-editor.htm), it works fine in Safari... But wherever i put the code in my web page, it doesn't work... ???
Probably a bad interaction with rest of the page, couldn't figure out where.
If someone has a suggestion, it is highly welcome.
By the way, I am trying to use Blockly for a project and this image is generated and included in the Blockly SVG. I almost succeeded to include an editor in a Blockly bloc.
Damir
<svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="250px" height="50px">
<image width="200px" height="40px" xlink:href="data:image/png;base64,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">
</image>
</svg>
It doesn't work in Chrome either.
The problem is that your base64 encoding is awry. Delete the two equals signs at the end of the data URI:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="250px"
height="50px">
<image width="200px" height="40px" xlink:href="data:image/png;base64,iVBORw0KG
goAAAANSUhEUgAAAMgAAAAyCAYAAAAZUZThAAAFx0lEQVR4nO3azWsTWx/AcdfnD8h2VlllIWTRh
RAohBK6KyG4iuiqGHAR7NIXCAhiQKygIb5QlQqtlsZaXKQgiqFV0GkrqDE1NhVNqUlro3ltnUy+d
3HJXNPeZ7hgoX3s7wNn08x0TsN8Z84kPZDJZEin0zJkyNgyMpkMB3RdRwixna7rEogQ/4sEIoQNC
UQIGxKIEDYkECFsSCBC2JBAhLAhgQhhQwIRwoYEIoQNCUQIGxKIEDYkECFsSCBC2JBAhLCxrwMZG
RkhmUzu9jTEHravA/H7/Vy6dGm3pyH2sH0dCECz2dztKYg9bMcCWV1dpb+/H6UUhw4dIpVKAZBKp
QgEAiwuLgKQz+cJBoM8fvyYVCrFmTNniEajKKXQNI32XFZWVjh+/DgPHjxA0zRmZ2fZ2NhgcHAQp
RQOh4Ph4WFM07S2DwaDKKVQSjE5OWnNbWxszPp5MBikWCwCcOvWLWu7crnMwMCAtd21a9eseK5fv
86VK1c4d+4cSimcTicLCwu//Z6JvW9HAimXy7jdbvr7+0mn0wwPD6OUYnp6mo2NDbxeLz09PVQqF
Xp7e/F6vRiGQSKRQClFOBzm8+fPnD17FqUUi4uLZLNZ62S9ceMGxWKR/v5+nE4nuq7z9OlTlFIMD
g7SarXo7e0lHA7z5csXHj16hFIKXdfRdR2lFDMzMywuLuL3++nq6sI0TY4ePUosFsMwDLxeL93d3
Xz48IHp6WmUUkSjUQDC4TBKKS5cuMD8/Dx9fX34fD4rTvHn2pFAEokEmqaxtrZGs9mk1WoRCoUIh
UK0Wi3y+Tyapll3iXw+b+138OBBfv78CYBpmvh8PuLxuBXI/Pw8AB8/fkQpxdzcnHXckZERXC4X6
+vreDwewuEwKysrAGSzWUqlElNTUzgcDlKpFI1Gg0qlYl39Q6GQdSyHw2HdWQCSySSaplEulwmFQ
pw8eZJWqwXA69ev0TSNUqn0W++b2Pt2LJD21f7XceTIEesqe/78eZRS3L5929pvfHx825X4xIkTx
GIxstlsx0n46x3l1+F0OimVSrx69Qq32239/PTp06yurmIYhnXs9vJvamoK+CeQRCKBy+WiXq9b8
/j06ZN1/FAoxNDQkPXa1rmJP9eOBDI6OorL5aJarbK5uYlhGMzNzfH+/XuAbXeQr1+/An8H0tPTY
wXSarXw+XwMDw9vOwkXFhZQSpHL5Wg2mxiGwdLSEjMzMxiGQTqdxjRNSqUSL168wO12E4vFyOfz1
l0ll8tx9erVjhM/Ho+j6zqaplGpVKy/aesdJB6PW69JIPvHjgSSyWRQSjExMYFhGLx58walFHfv3
sUwDHw+H4FAgO/fv+PxeAgEAh3PIA8fPqTRaDAxMWFFsPUkbD/nRCIRarUaxWIRj8fDsWPHqNfra
JrG0NAQrVaLarVqLdVGR0dxOp0sLy8D8OzZs22BlEolNE3j8uXL1Ot18vk8XV1dRCIRANtA1tbWO
HXqFEtLS8Dfy69IJEK1WsUwDC5evMiTJ09+6/0Vu2fHPsVKJpMdS59oNIppmty5cweHw0EulwPg3
bt3KKW4f//+vy7N2kuwX5c4bdlsFpfLZW3r9/utq/7k5GTH7+nu7ubbt2+Uy2X6+vo6XhsbGwNgY
GDAOvFfvny5bXlYrVa3bdeeR/uO0176zc7OAv88j5VKJRqNBm63u2Nf8f9lR78HqdVqrK+vdyxV7
IyPj3P48GFM06RYLP6n/ZrNJuvr6/z48WPba5VKhUKh0PGw3VYsFikUCrbH2NzcZHl5mUKh8J/mL
/58u/pF4b179+jq6pIv68SetauBPH/+nJs3b1ofnwqx1+z7fzURwo4EIoQNCUQIGxKIEDYkECFsS
CBC2JBAhLAhgQhhQwIRwoYEIoQNCUQIGxKIEDYkECFsSCBC2JBAhLAhgQhhQwIRwoYEIoQNK5Bar
SZDhowtQ9d1DqTT6crbt29rMmTI6BzpdLryF7moXnnVwmHFAAAAAElFTkSuQmCC">
</image>
</svg>

SVG text line height displays differently within img tag

I have created an SVG image which I am using within our website.
The SVG is displayed by inserting the XML into the HTML file, however, when loaded like this the SVG displayed differently compared with being displayed within an img tag.
<img src="http://elbrus.ecommercesuite.co.uk/Customisation Tool/SVG Templates/Bookmark.svg" />
I am just trying to reduce the line height within the following SVG:
https://jsfiddle.net/fahc2vvq/
I have to load in the XML version to edit the SVG within the website, Any ideas?
If you want a <foreignObject> to function correctly, you need to include a <body> element.
Note: I've removed the image from this demo to make it smaller.
<img src="http://elbrus.ecommercesuite.co.uk/Customisation Tool/SVG Templates/Bookmark.svg" />
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="73mm"
height="150mm"
viewBox="0 0 73 150"
version="1.1"
id="svg4523">
<g
id="layer1"
transform="translate(0,-147)">
<foreignObject
x="15"
y="150"
width="40"
height="60">
<body>
<p id="credit-card-text" style="font-size: 4px;text-align:center;text-anchor:middle;fill-opacity:1;font-weight:bold;line-height: 1;">Customise with your own message here.</p>
</body>
</foreignObject>
</g>
</svg>

SVG element width and height set in html but appearing as 0 0 in inspector

I have an svg rect like this:
<svg class="legend-square">
<defs>
<pattern id="pattern1" width="3"
height="3" patternunits="userSpaceOnUse" patterntransform="rotate(-45)">
<rect width="2" height="3" transform="translate(0,0)" fill="purple"></rect>
</pattern>
</defs>
<rect width="12" height="12" fill="url(#pattern1)"></rect>
</svg>
When I inspect the second rect with Chrome it has no width and height. There are no CSS rules applying to it. Why doesn't it get affected by width and height?
One of the reasons why SVG file is rendered on front-end with zero height and width is missing <svg> tag attributes "height" and "width".
Incorrect:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 49 30">
Correct:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 49 30" width="49" height="30">
It works fine.
If the snippet works individually but size of div containing it in you code appears 0x0 then look into : Why is my div's height zero
Its usually caused when float is set.
<div>
<svg class="legend-square">
<defs>
<pattern id="pattern1" width="3" height="3" patternunits="userSpaceOnUse" patterntransform="rotate(-45)">
<rect width="2" height="3" transform="translate(0,0)" fill="purple"></rect>
</pattern>
</defs>
<rect width="12" height="12" fill="url(#pattern1)"></rect>
</svg>
</div>
You really haven't provided enough information. For instance, what is the parent element of your SVG?
Just because your <rect> has a width and hight, it doesn't mean your SVG does. SVG is not like HTML, where elements expand to fit their children. SVG is like the <canvas> element. You have to make sure it either explicitly (or implicitly) has a size.
You have not specified width or height attributes for your <svg> element, so they are both defaulting to "100%". What they are 100% of depends on what size the SVG's parent element is. Hence my first question above.
For an 'inline' SVG element you have to apply the styles, inside the svg element itself.
inside the <defs></defs> tags. Since it has its Own DOM[Document Object Model], Css Apllied to it from Outside, will have no effect.
You have Several different options for embeding an SVG, You can use it inline as in your example where you declare the <svg></svg> inside of your html/php document or you can use one of the many other methods listed below;
embed an: ..............................................<img src="../pathtoyourSvg"></img>
embed as an img with a fallback option: <img src="logo.png" srcset="logo.svg" alt="My logo">
use an: ....................................................<object type="image/svg+xml" data="image.svg">
<!-- Your fall back here -->
<img src="image.svg" />
</object>
use: .........................................................<embed type="image/svg+xml" src="image.svg" />
use an: ....................................................<iframe></iframe>
embed the Svg inside of a canvas element using Javascript:
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
}
img.src = "path2your.svg";
You may Also Embed the Svg using Css Background image,
ie:
.mySvgContainer{
background-image:url('PathToMySvg');
}
But from the comments & Questions I have read, this need to be either Url or Base64 encoded, which seems a bit Hacky and not very convenient.
each of them have their own advantages and disadvantages.
Because of security reasons, some SVG embedding methods will block access to external resources including CSS, fonts and javascript. Especially when we have multiple images, ideally our embedding method should be able to refer to a single CSS, font or javascript file (to save resources) and be able to manipulate our embedded SVG.
Also worth mentioning that if you have display:flex; attached to an elemnet or its parent then the width and height values will have no effect on the flex items. So It may appear as 0, 0, in the console.
Some Useful Information & related questions:
Svg Coords & Units w3.org
Svg Width - Height
Applying Styles to an embedded Svg
You can wrap your svg element inside the html5 object element.
<style type="text/css">
object{
width:300px;
height:200px;
}
object svg{
width:100%;
height:100%;
}
</style>
<object>
<svg class="legend-square">
<defs>
<pattern id="pattern1" width="3"
height="3" patternunits="userSpaceOnUse" patterntransform="rotate(-45)">
<rect width="2" height="3" transform="translate(0,0)" fill="purple"></rect>
</pattern>
</defs>
<rect width="12" height="12" fill="url(#pattern1)"></rect>
</svg>
</object>
You can set height and width on the object element just link any other html element while you can set height width to 100% for SVG element. It will work. But first, test your SVG by opening the file directly in chrome.

Modifying SVG after it has been loaded

How would I modify an SVG file after it has been loaded by the browser, preferably through jquery? A simple example would be pressing a button and the color of the SVG element changes. Any documentation would help as well.
EDIT: This link helped a great deal:
w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML
You can't "modify" SVG files (except by changing them on the server). SVG files define a collection of SVG objects, each of which can be identified with an ID, if you wish. These objects can be manipulated with JavaScript like you would any DOM element (e.g. setAttribute, etc). Check http://www.w3.org/TR/SVG11/types.html#BasicDOMInterfaces for the DOM interfaces. Notice that SVGElement extends Element, which is the basic DOM element type.
EDIT: simple example:
<html>
<body>
<input type="button" onclick="doSVGThing()" value="change">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect id="aRect" x="10" y="10" height="100" width="100"
style="stroke:#ff0000; fill: #9999ff"></rect>
</svg>
<script type="text/javascript">
function doSVGThing() {
var r = document.getElementById('aRect');
r.setAttribute('style', 'stroke: #00ff00; fill: #99ff99');
}
</script>
</body>
</html>

Categories