Troubles resizing SVG in Raphael - svg

I am trying to draw this svg of europe using raphael. For each path in the svg, I've parsed it and do: r.path([countrypath]). This works, but the problem is that it is gigantic. For example, some of the paths look like M 11689.234, 6005.2561... It isn't even coming close to fitting on a 500x500 canvas. How do I resize this? Raphael's scale/translate don't seem to work, or I don't know how to use it. I noticed in the SVG each path has transform="translate(5.875e-4,7.538462e-5)" Do I need to somehow change the viewBox? Or change the svg path's somehow before it touches Raphael?

you can use scale(Xtimes,Ytimes,centreX,centreY)
where Xtimes,Ytimes are the proportion reduction if you select 0.2 the images would be reduced to 1/5th
and
centreX, centreY are relative coordinates where you should select 0,0 so that all paths/parts of svg are scaled down uniformly and relatively
if you select scale(0.2,0.2,0,0) your image would be properly reduced to 1/5th

I actual picked out quite a large SVG of the world yesterday and fed it through the SVGTOHTML converter.
You will find the tool and associated info #
http://www.irunmywebsite.com/raphael/svgsource.php
I set up a whole load of resources for Raphael #
http://www.irunmywebsite.com/raphael/raphaelsource.php
Amongst these you will find the world map wrapped in the scale pluton provided by Zeven!
The 20minute exercise delivered this...
http://www.irunmywebsite.com/raphael/colourmap2.php
Hopefully this will help you or someone with a similar problem in the future.
Also note that you can simplify paths in SVG editors as well as scale them before you put them in the SVGTOHTML converter.
Quite often maps can be drawn to extreme detail but simplifying them will greatly reduce path length.

You have two options either use what I did, use the .transform("transform string") to scale the paths, the transform string can be sww,hh,xx,yy where ww and hh is by how much you want to scale the path.
.transform("s0.25,0.25,0,0");
You can find an EXAMPLE HERE or jsfiddle HERE.
Or use
paper.scaleAll(n);
where n is the amount by you want to scale the whole paper by. First create the path in the page and then scale the paper object by maybe half
paper.scaleAll(0.5);
You can find the library and examples for the Scale.Raphaeljs library in the link below:
Scale Raphael library

Translating by such a small amount seems a bit wasteful, it's ~0 anyway, I doubt you'd see much of a difference if you stripped off the transform attributes that look like that.
Yes, changing the viewBox could make it fit to whatever you wanted in all viewers that support SVG, but raphael itself doesn't support viewBox (you'd have to provide some VML fallback yourself).
Either preprocess the path data to fit your particular use (probably a good idea anyway, it always helps to keep the filesize down, wikipedia maps are usually quite large) or use raphael's scale function to scale the paths to a proper size.
Update: Raphaƫl v2.0 and later does support viewBox (via the setViewBox method).

You can use the Raphael attribute 'translation', which takes an x,y delta. ie:
r.path([countryPath]).attr({translation:'-11689, -6005'});
To make it more reusable for multiple paths, you could parse the x and y values from the M in your svg path. When I did this, it turned out that I didn't want my path to be exactly on the 0,0 since that sent it over the canvas as well -- might take some adjustment depending on the height and width of your element.

Related

Logic for "Erase SVG Stroke"?

Problem
Hi,
So I have noticed that software like Microsoft Edge and OneNote and Notability, store hand drawn strokes as vector curves or lines. They also provide the ability to erase strokes, by dragging the eraser over them.
I wanted to implement something similar in my software, an SVG Animation and Creation bundle, and I have come up with the logic for the freehand stroke to SVG curve, a demo is available here:
https://phantomzback.github.io/SvgFreehandDrawDemo/polylineTest.html
It uses the polyline tag with the cursor positions, and path simplification is something I also plan to implement. But before that, I need a way to detect if the eraser has gone over the stroke. I have an approach but I am not sure how great of an approach it is. I'd appreciate advice on how this can be improved or alternative methods to tackle the problem.
Current Idea
Find the pixels where the stroke is rendered, and save it in an array. Then, check for if the eraser tool is active and goes over that stroke. If it does, delete this stroke.
Finding the pixels shouldn't be very hard since a polyline is a bunch of points and lines drawn between them. But I plan on adding support for paths later, for which a better approach might be needed.
Thanks in advance!

svg graphic: fixed and scalable

I draw graphics for my program in corel draw (x6),
after that export it as svg files, and my program
uses this svg files.
Let's say I draw "arrow" in corel draw program.
It consists of tip and line.
I need to show this "arrow" in my program,
but I need "tip" part to be not scalable,
while "line" should be scalable.
The most simple solution which works, split "arrow"
into two parts, convert "tip" part to bitmap during program starts.
But it requires too much time for complex pictures.
And I wonder, is it possible in svg format to say this part should
not be scaled, and this should? And how this can be exported from corel draw?
I found something suitable in corel draw, to play with scale for diffrent parts of picture,
but during export to svg all my definitions was lost.
Unfortunately, there is no concept of a non-scaling element. At my last job, I worked with the SVG working group to try to get this feature introduced (nonscaling elements are really useful in engineering drawings), and it is on the roadmap for SVG 2.
The issue is SVG-ISSUE-2400.
The way to do this for now, is to implement a zoom event, that dynamically rescales nonscaling elements when the zoom level changes.

How do I alter the stroke width along a path/line?

Having read the SVG2 draft, I am slightly disappointed to learn that there will be no new line caps than the standard 3. The new arc line join is brilliant however, but not what this question is about (I just wanted to mention that).
I had been hoping for a cap that ends in a triangle. But given my use case, that might not be ideal either.
As far as I can gather, Adobe Illustrator - which I do not use myself - allows the width of a stroke to be variable. This is useful when drawing from a drawing tablet, to highlight the pressure of the lines. It's true, this functionality exists in many bitmap drawing programs, but is there a way to achieve this effect in SVG, without having to draw multiple lines?
The idea is that each node should have a width, and the lines should then 'smoothly' scale the width between each node that had a different width.
Is this possible? And if not, could it be considered?
P.S. I should point out, that this is more a thought experiment and an idea than something that hinders my process. More of a nice to have than need to have.
While this may not be a true answer (SVG standard wise at least), it turns out that in the current trunk version of Inkscape, this feature called PowerStroke already exists. There are some screenshots of PowerStroke.
This should satisfy my quest for the time being.
It turns out - as well - that the arc line joins was actually suggested by Inkscape as well, they are just called extrapolate in Inkscape.

Cleanly morph SVG paths

In this fiddle I am trying to morph the small H into the big H by simply extending the ascender. I thought it would be as simple as just providing the new path and letting Raphael work its magic, but apparently that's not the case.
Is there an easy way to elongate the ascender without having it mangle up first? Note this is one moving piece out of a much larger logo.
As far as I can see from the draw path, the two shapes are not drawn from the same starting point - so you're getting mangling.
SVG animation will always try to morph the first segment of the start shape into the first segment of the end shape. If the draw order is different, then you'll get strange effects like what you're seeing.
(And please note that you must have the same number of segments and the same order of path types in the start and end shapes.)

SVG/Raphael: All paths through a given point?

I'm using RaphaelJS to implement some event-heavy SVG. I have a set of paths on a canvas, and a point. How can I get all the paths that cross that point? Relatively new at this, but I assumed this would be trivial and I can't find anything about it.
If it helps, the specific implementation is trying to detect on the mousedown event if I've clicked on a path so I can rotate it around another point onmousemove.
Unfortunately, I'm not aware of a portable (supporting both the SVG and VML backends of raphael) way to do this without implementing the math yourself. However, for browsers that support SVG, the SVG spec includes built-in support for exactly what you are requesting:
http://www.w3.org/TR/SVG/struct.html#_svg_SVGSVGElement__getIntersectionList
Vector is math. Find the equations of the lines and see if the point fulfill the equation.

Resources