I have a big (12 MB) SVG file containing many curved paths all having the same stroke width. Now I'd like to transform the stroke-width in a way that it depends on some mathematical function which takes the coordinates of the path segment (or even better: of the actual points on the path segment) as input.
The only way i found so far is to cut the paths in segments using inkscape and then modifying the stroke-width using the etree library for python. But what I really want is continuously decreasing/increasing stroke width like in inkscapes calligraphy tool.
Related
I am importing an SVG using the SVGLoader and turning each path into a mesh that is then put into a group. When I do so, the group is much larger than I would like it to be. Rather than scaling, I'd like to import it at the correct size to begin with. When I change the width and height attributes on the SVG: <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25"> nothing changes with respect to the size of the rendered meshes. I haven't seen anything actually describing how SVG sizes are determined by the loader. Is it a viewbox? Is there something special that has to be done?
In your 3d world, you can only change the size of your object by Object3D.scale.set(x, y, z),and the x, y, z value determine the size of your mesh in you 3d world. When you change the width and height attributes on the SVG, you can only change the resolution but not the size
I have one SVG image file, having some paths. Something like:
<svg>
<g>
<path id="land" class="land" d="M108.114,402.043l0.683,1.604l-1.204.(truncated)">
<path id="ice" class="ice" d="M288.114,402.541l0.683,1.604l-1.204...........">
<path id="water" class="water" d="M038.114,402.543l0.683,1.604l-1.204........">
</g>
</svg>
I need to know which path was clicked. When I load SVG image file in Phaser using load.svg(), the event is triggered for the entire image and not just for the area (or path).
So, how can I detect which path was clicked? Any help is appreciated.
Might be using the wrong terms, but the SVG loader paints the projected SVG to a static bitmap texture. This eliminates the existence of these pathed objects. Even if you split these paths into their own SVG and layer them, the hitboxes for textures is going to be rectangular, based on the size of the texture.
If you separate these paths into their own SVGs, a more computationally expensive hitbox exists, with pixel-perfect enabled for the hitbox setup Docs Phaser3 #makePixelPerfect. This will look at the projected texture and apply a hitboxArea over the pixels that each SVG renders.
A less expensive hitbox for each SVG would be to implement a custom hit test function when the input manager tests for pointer-events. Docs Phaser3 HitAreaCallback. This is going to be more difficult, and its difficulty depends on the shape of the hitbox you are going for, and how accurate you need this hitbox to be. Basic geometries and contains methods for hit tests can be found in Phaser.Geom namespace, if those don't match your use case you would need to write/find a function yourself.
I have an independent SVG image with no filling (fill="none").
I would like to fill it with color, but when I change fill="none" to fill="blue" for all paths, my file becomes a blueish mess:
Source SVG file: https://ufile.io/yaj33
Your SVG is not "clean". It is made up of several hundred open (ie. not closed) path elements. If you want to be able to fill your drawing easily, you'll need to make an SVG with a smaller number of closed shapes, perhaps one for the head, one for each arm and leg, and two open paths for the eyes.
I have one or more path elements inside a g element that I am scaling to fit inside a grid rectangle. The transform is applied to the g element. My transform works in that all the points end up at the right places, but I discovered that I have to adjust the stroke-width of the path to get a readable line.
The problem is that if the scale involves a large shift in the aspect ratio, I end up with some segments of the path being heavier weight than others, depending on their orientation.
Here is a typical transform that my code computed:
scale(0.1875, -0.010397820616798718) translate(-1149000, -96174)
In this case I end up changing the stroke-width from 9px to about 48px. Segments close to the horizontal end up thin, those close to the vertical are thick.
Is there any easy way to end with all the segments with the same rendered width?
Have you looked at setting the vector-effect attribute to non-scaling-stroke?
<line vector-effect="non-scaling-stroke" stroke="black" stroke-width="5"
x1="32" y1="50" x2="32" y2="350"/>
http://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke
UPDATE
The best solution I can think of is to manually transform the coordinates of your path.
vector-effect="non-scaling-vector" is not consistently supported. My versions of Firefox and Safari do not support it, but my Chrome browser does.
In the SVG standard there is no way of specifying a transformation for the stroke independantly. (A stroke-transform attribute would be nice - like the windows GDI+ drawing system, where a Pen object has it's own local transformation).
Until this changes, the best solution I can think of is to manually work out the coordinates of your path - that is the svg has no transform elements; the coordinates are already transformed.
I am trying to copy paths from inkscape into Raphael (individual countries), the problem is the moveTo is way off, how do I make it display on the relatively correct position on the canvas?
If you're trying to draw a path on a canvas in a relative position, you need to transform all of the absolute coordinates to relative coordinates. I had the same problem recently and resorted to a calculator and paper (it was a short path, and wasn't worth it to attack programatically). There are a few tools out there that claim to be able to do these transformations, but in my experience they were either incomplete or outdated links.
The problem is that Inkscape has already decided for you that you want your SVG files optimized for size, and will switch back and forth from relative to absolute whenever it would save a few bytes. Essentially, what you would need to do is iterate through the path, keeping track of your position, compare each absolute node to the previous node (or the origin, if it's the initial moveTo), and replace any absolute coordinates with the difference.
The Inkscape preferences have an option to force absolute coordinates, (uncheck Preferences->SVG Output->Allow relative coordinates) which may make the transformation a little easier.