UIBezierPath subpaths which forms closed path cannot be represented in SVG - ios

i need to convert UIBezierPath to SVG.
my UIBezierPath internally has collection cubic bezier paths as subpaths.
these subpaths when taken together forms a closed path, meaning, the last cubic-bezier's endpoint is same as first cubic-bezier's startpoint.
when i draw this path on a CAShapeLayer with some fill color, the overall path is filled with given color correctly.
now, I need to simulate the same behavior in SVG ( which is loaded inside a webview ), problem is the sub-paths are independent in svg and i can't combine them (group them) into a single path, so we lose the contextual information that this collection of paths are closed and hence fail to fill.
i tried to put these svg cubic-beizer path inside g element , that didnt work either. like below
<g>
<path d="M1013.3,1228.7 C1007.1,1238.4 991.4,1242.6 984.2,1242.6" />
<path d="M984.2,1233.6 C995.1,1237.3 1008.3,1231.7 1013.2,1231.7" />
<path d="M1013.2,1221.3 C1018.0,1210.9 1013.8,1197.1 1004.0,1197.1" />
</g>
how do i solve this problem ? any inputs are appreciated.
Thanks,

I'm not sure to understand, but you can use as many beziers path as you want in the same curve. Here is a way: http://jsfiddle.net/74os2um3/
Just put it in one <path> and add a Z to close it.
<path d="M1013.3,1228.7 C1007.1,1238.4 991.4,1242.6 984.2,1242.6 L984.2,1233.6 C995.1,1237.3 1008.3,1231.7 1013.2,1231.7 L1013.2,1221.3 C1018.0,1210.9 1013.8,1197.1 1004.0,1197.1 Z" />

Related

GIMP how to select from merged path

I have the path, merge from 8 subpath (because it require symmetry, I create 1/8 then merge them together)
I wanna select the picture inside the path, that is... impossible. Are there any ways to:
re-order the points inside the path
or
manual set the points position (x and y coordinate)
or
unclose any subpath (I hate this, hate to do drawing the paths over again)
or
anyway it select inside the path smarter?
thank you all.
The best you can do is splice the strokes so that you have a truly closed stroke from which you get a selection.
The ofn-path-edits plugin has a Join strokes function to connect together strokes whose end points are close enough.
But you'll have to redo part of your work: use the Join strokes function to create the closed shapes, then replicate+shift these closed shapes. And yes, this means that between the shapes, there are overlapping strokes, one for the shape on the left/top and one for the shape on the right/bottom.
At the same place there is also a path-mirror script that can create the symmetry of a stroke, and connect the ends that are on the symmetry axis.

svg linejoin imlementation differs in different applications

I write an svg parser.
I have an svg file with the following string:
<polygon fill="#969696" stroke="#323232" stroke-width="0.5" stroke-miterlimit="10" points="555.583,394.805 564.085,394.805 564.02,394.817 568.896,399.655"/>
And this picture looks different in various applications. Possible cases:
1)linejoin = bevel
2)linejoin = miter (Corel Draw)
3)two nearest points are not connected (Inkscape, adobe illustrator)
The second and the third case look look like:
It seems that svg documentation advices to draw the same picture as corel draw draws (right picture). But it is not very pretty.
So what rule will allow to achieve the left picture?
You seem to have a bogus co-ordinate in your polygon. The polygon has 3 vertices but you're supplying 4 and the bogus one is confusing things. Try this instead...
<polygon fill="#969696" stroke="#323232" stroke-width="0.5" stroke-miterlimit="10" points="555.583,394.805 564.085,394.805 568.896,399.655"/>

LinearGradient for path SVG

I need to fill a path which is created dynamically using javascript. I've created a gradient for that and used that to fill my path, but nothing happened. What's wrong with my code?
$('svg').prepend('<defs id="gradient"></defs>');
$('#gradient').append('<linearGradient id="yellow" x1="0%" y1="0%" x2="100%" y2="0%"> </linearGradient>');
$('#yellow').append('<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" /> <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />');
$('g:nth-child(2n+1) path').attr('fill','url(#gradient)');`
Your fill points to a defs element and not the linearGradient. The id="gradient" should be on the linearGradient element - or alternatively make the fill url(#yellow)

How do you animate an SVG path in IOS?

I have an SVG path like this:
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" version="1.1" baseProfile="full">
<path d="M47.16,66.38c0.62,1.65-0.03,2.93-0.92,4.28c-5.17,7.8-8.02,11.38-14.99,18.84c-2.11,2.25-1.5,4.18,2,3.75c7.35-0.91,28.19-5.83,40.16-7.95" style="fill:none;stroke:black;stroke-width:2" />
</svg>
I can render the path but can't seem to find a way to make the path animate so that it looks like it is "being draw" as if with pencil. The animate node works for single coords but not for paths.
I will eventually end up using this animation in an iPhone app either with a parser or with a UIWebView.
Try animating the 'stroke-dashoffset' (note that you need a matching 'stroke-dasharray' with it), see this example. The length of the path that needs to be computed to be able to use this successfully can be fetched via script like:
var pathlength = yourPathElm.getTotalLength()
View source on the example to see how it's done.
I tried for a long while to do this without having to add extra scripts to the header (that I have no idea of javascript didn't help), so here's the solution:
<path d="..." stroke-dasharray="">
<animate attributeName="stroke-dashoffset" from="" to="0" dur="1s" begin="0s"
onload="var length = parentNode.getTotalLength();
parentNode.setAttribute('stroke-dasharray',length+','+length);
this.setAttribute('from',length)" />
</path>
I added extra line breaks for readability here.
This is legal in SVG (although not in HTML) because the svg:animate element allows onload, which most HTML elements do not.
Once you've rendered your SVG path, to make it look like it's being drawn with a pencil, you could simply cover it all with an opaque layer, and then animate the movement of this layer along the path.
To find the CGPath along which you'll move the layer you can use this library:
https://github.com/arielelkin/PocketSVG
This will parse the SVG data into a UIBezierPath. Then:
SvgToBezier *myBezier = [[SvgToBezier alloc] initFromSVGPathNodeDAttr:#"M176.17,369.617c0,0,335.106-189.361,214.894,38.298s129.787,282.978,178.723,42.553C618.724,210.042,834.681,87.702,790,307.915" rect:CGRectMake(0,0,1024,768)];
UIBezierPath *myPath = myBezier.bezier;
CAKeyframeAnimation *mySVGPathAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position"];
bounceAnimLeft.duration = 3;
bounceAnimLeft.path = myPath.CGPath;
[myObjectToMove.layer addAnimation:mySVGPathAnimation forKey:#"pathAnimation"];

Put label in the "center" of an SVG path

I'm trying to draw a label on a polygon of an svg file. The problem I'm facing is to find out roughly the center of this polygon to place the label, as the path's coordinates are in svg format and need to be parsed. Is there an easier way to determine the center of an svg polygon (maybe someone can point out a javascript library or a snippet)? I'm using Raphael javascript library to manipulate the svg, but it doesn't seem to go beyond the standard svg functionality.
You could try the following approximation for doing something similar to the polygon suggestion, based on SVG DOM methods:
var totalPathLength = pathelm.getTotalLength();
var step = totalPathLength / 100;
for(var dist=0; dist < totalPathLength; dist+=step)
{
var pt = pathelm.getPointAtLength(dist);
addToAverage(pt.x, pt.y);
}
I think the simplest approach is to use the center of the path element's boundingbox (pathelm.getBBox()), that's simpler than the polygon suggestion.
The simplest thing you could try doing is to calculate the center by taking the average of all the points in the polygon. It should work for all but the most irregular of polygons. I've used the same algorithm to good effect in my programs.
Best of luck.
Insert a text tag inside the svg and position it by calculating the width and hight
<svg width="447pt" height="559pt" viewBox="0 0 894 1118" version="1.1" xmlns="http://www.w3.org/2000/svg">
............
............
<text x="450" y="300" font-family="Verdana" font-size="15" fill="red" >
Text To Show
</text>
</svg>

Resources