Logic for "Erase SVG Stroke"? - svg

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!

Related

Good practice for using almost identical sprites in phaser. Alternatives to using more sprites

So, I have been working in Unity but I've decided it's time to change to something I know better: JavaScript. I've been considering switching to Phaser.js but I have some questions regarding an issue I've been having even in Unity and that I found no solution to at the moment while searching on the internet. I have no code to provide as I haven't yet started actually programming in Phaser, so I'll try to be explicit.
My game idea basically revolves around some lights that change colors. The sprites I have for the lights look identical, but just with different colors, but not entirely (only parts of them are colored differently). The problem is that my game has many different colored lights and it has to change between them. Like, if one light is red and you click on it, it becomes green, for example. Creating and loading so many sprites that look almost the same seems like a bad practice, and I wonder if there is a way to change the color of a sprite or a part of the sprite by code. I know that Phaser doesn't support svg and that svg in games is a bad idea in general because of performance issues but it would have saved me a lot of time to just add the generated svg code of the sprites I use and just change the fill of the parts I want.
So, my question is: what are the best alternatives (if any) to using multiple sprites or how can you change the color of specific parts of them?
Another alternative, depending upon your light sprites, is to use Phaser's tinting capabilities.
Both sprites and images in Phaser can be tinted, and since Phaser supports sprite grouping, even if you wanted to change only a part of the image you could easily have each displayed object consist of two sprites, one of which is the same for all lights (the part that doesn't change) and another that is also shared, but tinted.
Phaser 3 example of tinting an image:
this.add.image(300, 300, 'pixel').setTint(0xff0000);
Phaser 3's setTint() documentation.
Phaser 2 CE example of tinting a sprite, in case you're looking at using this version:
sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'atlas', 'greenJellyfish0000');
sprite.tint = Math.random() * 0xffffff;
If the lights don’t have to move, then you can just have a few images and change their src’s. Alternatively, I believe you could have it so that when the sprite is clicked it changes to a different looking animation. That is, after all, the point of a spritesheet, isn’t it?

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.

How do I connect two arcs with a line in this d3.js visual

I saw an infographic online that I wanted to use as a challenge to learn d3.js. The original infographic is here:
http://www.shah3d.com/wp-content/uploads/2012/11/IG-WWF-Dehahs.png
I've made a start here:
http://www.tips-for-excel.com/d3test/arc/arc%20test.html
You'll notice that the original has nice lines that link an arc from the bottom with an arc along the top. So far I can only think of painfully placing lots of circles to achieve this effect, hence the odd red circle currently in my visual. What would people's best methods be to replicate the original graphic? Which element would make this task easier? Arcs? Lines? I imagine I'll have to manipulate my data so that the lines go where they're meant to.
Happy to give more info if needed and thanks for taking time to read this.
There are a few existing diagrams to work off of from d3's galleries:
http://bl.ocks.org/4062006
http://bost.ocks.org/mike/uberdata/
Both use the length of the chord as the width of the stroke (initially), but you can tinker with that, for sure.
Graphically, you could use arcs, or full circles with a clip around it. As to the 'best' way to do it, that may come out of 'requirements' of how your graphic needs to behave (animation, relative arc placement, etc).
Personally, I'd go with path arcs.

Troubles resizing SVG in Raphael

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.

Resources