What determines if a svg can be rendered by openlayers - svg

I've got 3 different SVGs that all display a marker. However only one of them works with the Openlayers icon. In this example only svg1 correctly displays the marker on the map. All three SVGs are correctly displayed when using an IMG element. What determines if a svg can be displayed by openlayers or what do i have to change to make it work?
var svg1 = '<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" width="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">' +
'<path fill="#156BB1" d="M22.906,10.438c0,4.367-6.281,14.312-7.906,17.031c-1.719-2.75-7.906-12.665-7.906-17.031S10.634,2.531,15,2.531S22.906,6.071,22.906,10.438z"/>' +
'<circle fill="#FFFFFF" cx="15" cy="10.677" r="3.291"/></svg>';
var svg2 = '<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" enable-background="new 0 0 30 30" version="1.1"><g><title>Layer 1</title><path id="svg_1" d="m22.906,10.438c0,4.367 -6.281,14.312 -7.906,17.031c-1.719,-2.75 -7.906,-12.665 -7.906,-17.031s3.54,-7.907 7.906,-7.907s7.906,3.54 7.906,7.907z" fill="#156BB1"/></g></svg>';
var svg3 = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="#156BB1" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"></path></svg>';
var mysvg = new Image();
mysvg.src = 'data:image/svg+xml,' + encodeURIComponent(svg1);
var style = new Style({
image: new Icon({
img: mysvg,
imgSize: [30, 30]
})
});

Apparently the order and the parameters used are of importance for Openlayers. I've got svg3 working by using the following as svg wrapper.
<svg version="1.1" id="Layer_1" width="30px" height="30px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512">
</svg>
Removing any of those parameters or changing the order resulted in the svg not showing on the map. Another issue was that the path values were not comma separated. That poses no issue with displaying it in an image but openlayers seems to require it at least for usage within an Icon.

Related

Is it possible to change the thickness of lines in an svg without using an editor like Illustrator?

I have this svg:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 286.054 286.054" style="enable-background:new 0 0 286.054 286.054;" xml:space="preserve" width="512px" height="512px" class=""><g><g>
<path d="M143.027,0C64.031,0,0,64.04,0,143.027c0,78.996,64.031,143.027,143.027,143.027 s143.027-64.031,143.027-143.027C286.054,64.04,222.022,0,143.027,0z M143.027,259.236c-64.183,0-116.209-52.026-116.209-116.209 S78.844,26.818,143.027,26.818s116.209,52.026,116.209,116.209S207.21,259.236,143.027,259.236z" data-original="#2394BC" class="active-path" data-old_color="#2394BC" fill="#999999"/>
<path d="M150.026,80.39h-22.84c-6.91,0-10.933,7.044-10.933,13.158c0,5.936,3.209,13.158,10.933,13.158 h7.259v85.36c0,8.734,6.257,13.605,13.176,13.605s13.185-4.881,13.185-13.605V92.771C160.798,85.789,156.945,80.39,150.026,80.39z" data-original="#2394BC" class="active-path" data-old_color="#2394BC" fill="#999999"/>
</g></g> </svg>
It's a simple outer circle with a number in the center.
What I would like to know is if it's possible to change the width of the outer circle with editing the source or is that something that can only be done with Adobe illustrator or a similar tool?
As commented #enxaneta
The paths have no stroke. What you have are filled paths. You may try
to add a stroke the the circle the same color as the fill
(stroke="#999999") although you can replace the path with a
element with no fill and a stroke
Please try <circle r="130" cx="143" cy="143" fill="none"
stroke="#999999" stroke-width="25" />
instead of the path and change
the stroke-width as you need
As you can see in the figure, path has a double contour which is painted over.
Instead of path, add a circle.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 286.054 286.054" style="enable-background:new 0 0 286.054 286.054;" xml:space="preserve" width="512px" height="512px" class=""><g><g>
<circle r="130" cx="143" cy="143" fill="none" stroke="#999999" stroke-width="25" data-original="#2394BC" class="active-path" data-old_color="#2394BC" />
<path d="M150.026,80.39h-22.84c-6.91,0-10.933,7.044-10.933,13.158c0,5.936,3.209,13.158,10.933,13.158 h7.259v85.36c0,8.734,6.257,13.605,13.176,13.605s13.185-4.881,13.185-13.605V92.771C160.798,85.789,156.945,80.39,150.026,80.39z" data-original="#2394BC" class="active-path" data-old_color="#2394BC" fill="#999999"/>
</g></g> </svg>

Find svg viewbox that trim whitespace around

Assuming I have an svg that draws some paths, what tools should I use to find a viewbox that perfectly fits those paths so that all redundant space around is trimmed?
You can simply set your svg's viewBox to its Bounding Box.
function setViewbox(svg) {
var bB = svg.getBBox();
svg.setAttribute('viewBox', bB.x + ',' + bB.y + ',' + bB.width + ',' + bB.height);
}
document.querySelector('button').addEventListener('click', function() {
setViewbox(document.querySelector('svg'));
});
svg { border: 1px solid }
<svg version="1.1" id="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 300" enable-background="new 0 0 500 300" xml:space="preserve" width="250" height="150">
<path fill="none" stroke="#B2E230" d="M413.7,276.5c0,0,67-37,116,0c-24.1-33,16.4-53,0-34s-100-2-75-38" transform="translate(-75,-75)" />
</svg>
<button>setViewbox</button>
Note: It will also take into account the non-visible anchors of your pathes.

Proper SVG markup for external files to be loaded with Snap.svg

So here's the deal, I'm making some experiments with SVG and Snap.svg. I have an external SVG file, logo.svg, that was created with Adobe Illustrator, here's the markup:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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"
width="161.875px" height="144px" viewBox="0 0 161.875 144" enable-background="new 0 0 161.875 144" xml:space="preserve">
<polygon fill="#006098" points="144,144 27,144 57,0 144,0 144,54 161.875,72 144,90 "/>
<polygon fill="#00416A" points="57,144 0,144 0,0 87,0 "/>
<polygon fill="#98D5E9" points="72,57 72,27 87,27 117,27 117,57 117,72 117,94.5 117,117 87,117 87,94.5 57,94.5 57,72 87,72
87,57 "/>
<polygon fill="#288DC1" points="57,57 75.125,57 81.375,27 57,27 27,27 27,57 27,72 27,94.5 27,117 57,117 57,94.5 67.313,94.5
72,72 57,72 "/>
</svg>
I want to use this example and explore Snap.svg animations, so I'm loading it this way:
(...)
var s = Snap(element);
Snap.load('/images/logo.svg', function(f) {
s.append(f);
});
(...)
But for this to work my element must be a <svg>, so I end up with a <svg> inside a <svg>:
<svg logo-svg>
<desc>Created with Snap</desc>
<defs></defs>
<svg version="1.1" id="Layer_1" x="0px" y="0px" width="161.875px" height="144px" viewBox="0 0 161.875 144" enable-background="new 0 0 161.875 144" preserveAspectRatio="xMinYMin meet">
<polygon fill="#006098" points="144,144 27,144 57,0 144,0 144,54 161.875,72 144,90 "></polygon>
<polygon fill="#00416A" points="57,144 0,144 0,0 87,0 "></polygon>
<polygon fill="#98D5E9" points="72,57 72,27 87,27 117,27 117,57 117,72 117,94.5 117,117 87,117 87,94.5 57,94.5 57,72 87,72
87,57 "></polygon>
<polygon fill="#288DC1" points="57,57 75.125,57 81.375,27 57,27 27,27 27,57 27,72 27,94.5 27,117 57,117 57,94.5 67.313,94.5
72,72 57,72 "></polygon>
</svg>
</svg>
Somehow I fill this is a bit messy, is this correct? Or there's a better way to load external SVG files?
I think the principle is fine, ie often you may load quite a few SVGs and they need to be inside another SVG.
Plus Snap.load is actually taking a document fragment which needs appending to something. So to me it makes sense, but if you can highlight certain problems you are facing because of this, it could be there is a workaround.
I'm just going to post an example to adjust the main paper to the new svg which could be used...
var s = Snap("#svgpaper");
var bird = Snap.load("bird.svg", function ( loadedFragment ) {
var b = s.append( loadedFragment );
var bbox = b.getBBox();
var vbox = bbox.x + " " + bbox.y + " " + bbox.width + " " + bbox.height;
s.attr({ viewBox: vbox });
} );
testing example here

Align top polygon object

I'm rendering a triangle shape via svg. When it's at full width it sticks to the top of the div, but if I make the window smaller the polygon moves down. I tried to find a way to stick it to the top but with no success.
Here is the code.
<div>
<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"
width="100%" height="100px" viewBox="0 0 960 100" enable-background="new 0 0 960 100" xml:space="preserve">
<polygon fill="#22262E" points="959.746,0 480.882,96.009 2.018,0 "/>
</svg>
</div>
Please help me to find a solution.
Thanks.
Add preserveAspectRatio="xMidYMin meet" to your <svg> tag. It tells the renderer to position the content at the top centre of your viewport.

SVG rotation cuts off the edge

I am trying to rotate a SVG on a T-Shirt designer project but edges of the SVG are getting cut off. The code for the SVG is as follows:
Before Rotation (Everything is correct in this)
<g xmlns="http://www.w3.org/2000/svg" transform="scale(2,2)rotate(0,50,50)" id="clip1">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace" enable-background="new 0 0 100 100" viewBox="0 0 100 100" height="100px" width="100px" y="0px" x="0px" id="Layer_1" version="1.1">
<g>
[POLYGON CODE WAS HERE]
</svg>
</g>
After Rotation (One of the edges is getting cut off!!!)
<g xmlns="http://www.w3.org/2000/svg" transform="scale(2,2)rotate(45,50,50)" id="clip1">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xml="http://www.w3.org/XML/1998/namespace" enable-background="new 0 0 100 100" viewBox="0 0 100 100" height="100px" width="100px" y="0px" x="0px" id="Layer_1" version="1.1">
<g>
[POLYGON CODE WAS HERE]
</svg>
</g>
Everything in the above 2 codes is the same except for the rotate(...) function.
The screenshot of what is going wrong can be found here - http://i.imgur.com/Kr5Azx3.png. In the right side image, the elbow is cut off as well as the background behind that. The SVG file code is present here - http://pastebin.com/LfC7TkwV
Is this the default behavior of SVG rotation or am I missing some other tag to make this work? Any help will be really appreciated.
Thanks.
As Erik says, the rotate operation is causing part of the design to fall outside the viewport. You may have to add a small translate() to your transform, and/or enlarge the size of your viewBox so that it encompasses the new larger bounding box.

Resources