How to modified SVG file import to KonvaJS? - svg

i have an issue that's make admin can upload SVG and using it into Drawing Screen use Konva. The way to import that is ok, but ex-function i would like to ask is:
Is there a ways to help me can change size of that SVG such as inscrease stroke or make it bigger or smaller ?
Imagine the image below is a SVG i had import and import it to Konva Stage, then i would like to change this stroke to bigger than origin.
I had research a while but nothing got back, if you have any idea please comment. I'll read it all with all my respect.

TLDR: No you can't edit a complex SVG in any practical way.
In the comments you confirmed that you are using the Konva Path object and its superpower to consume an SVG drawing instructions as a string via its data() attribute.
This string is a codified set of data containing the SVG commands such as moveto, lineto, etc. To give you an idea of the complexity of the string format, the demo on the Konva site which draws a filled green heart looks like this:
var path = new Konva.Path({
x: 50,
y: 40,
data: 'M213.1,6.7c-32.4-14.4-73.7,0-88.1,30.6C110.6,4.9,67.5-9.5,36.9,6.7C2.8,22.9-13.4,62.4,13.5,110.9C33.3,145.1,67.5,170.3,125,217c59.3-46.7,93.5-71.9,111.5-106.1C263.4,64.2,247.2,22.9,213.1,6.7z',
fill: 'green',
scaleX: 0.5,
scaleY: 0.5,
});
The bad news - there is NO built-in way to access the individual drawing commands encoded in this string within Konva.
You can write your own code to manipulate this string if you wish - change the data string and pass it to the Path via pathObject.data(your_string).
Conclusion: I would look for another lib that can achieve this, to use instead or in addition to Konva. I very much like Konva, so my recommendation should underline that to try to edit SVG via mouse -> edit Path.data -> change drawing would be no fun.

Related

Ignoring <image> tag?? SVG NOT LOADING IN PROCESSING

I have a project due for University that involves SVGs, however mine won't load. All I get is:
"Ignoring image tag.
The width and/or height is not readable in the svg tag of this file."
Please help? I'm trying to load an SVG that has colour in it. This is the code:
PShape m;
void setup() {
size(1280, 720);
m = loadShape("mountain.svg");
}
void draw(){
background(102);
shape(m, 110, 90, 50, 50);
}
And if you need the SVG or something, let me know.
Thanks
I think I solved it.
just make sure that your artboard is bigger that your illustration.
For instance, If you set the artboard to fit bounds, then processing would mostly likely give you this message.
Another thing that I realised is that if you're using illustrator 2015, your SVG file will be moved to the left of the processing screen, and sometimes outside of it.
A workaround would be to put your illustration towards the top right of the screen, then save as an SVG file.
OR, you could just download illustrator 2014, you can do that from the creative cloud app on your computer. Just remember to always leave plenty of space for your illustration in the illustrator dartboard before you save.
I hope that helps!

Combining Multiple SVG Transformations

I'm new to Snap.svg and SVG and experimenting with transformations (an illustraiting plunk can be found here). Basically I'm trying to move, scale and rotate a shape according to its configuration. This is what I've found out so far:
rotating around a point is possible with rotate(angle, x, y)
there is no direct transform method to scale around a point but it can be done as described in "SVG Essentials"
However combining these transforms doesn't give me the expected result - my expected calculated center of the shape differs from the rendered one. Can anyone give me some pointers on how to correctly put these transforms together?
Regards,
Andi
To combine transforms, I would use Snaps own transformString format. I would first have a read of my previous answer on SO here, this is slightly different so posting a slightly different example and answer.
Whilst Snap can use SVGs transform strings (rotate() scale() transform()). They don't by default centre around itself for example, whereas Snaps (and Raphaels) do. This makes it a bit easier. For more complex situations, one may need to look into Matrix methods, but I think the following should be ok...
Snaps transformString uses string t (transform), s (scale), r (rotate), and you can add them repeatedly if wanted.
Here is an example of both methods, to highlight the difference.
jsfiddle here
s = Snap(400, 620);
var r1 = s.rect(0, 0, 100, 100).attr({
fill : 'blue',
stroke : 'black',
opacity: 0.5
});
var r2 = r1.clone().attr({ fill: "red" });
r1.transform('t100,100s2,2r45'); //typical Snap way, rotation/scale around centre
r2.transform('translate(100,100) scale(2,2,) rotate(45)'); //SVG way
The getBBox() method should be pretty reliable as far as I know (maybe post up a separate question on SO if you find an example where it is wrong)

RaphaelJS applying a custom transform

I am having trouble with applying a transformation to each path in my SVG. I know the exact transform I need to add as I am using a map from wikimedia and have tested it by adding it using firebug/chromebug.
I need to add:
transform="translate(0,239) scale(0.016963,-0.016963)"
This is an example of what I have:
http://jsfiddle.net/m7t4X/1/
If you inspect it, each path looks like this:
<path fill="#ff0000" stroke="#ccc6ae" d="M16760,5958C16752,5945,16745,5920,16743,5901C16740,5859,16734,5853,16710,5868C16694,5878,16690,5878,16690,5866C16690,5858,16696,5849,16703,5846C16709,5843,16705,5843,16693,5846C16670,5851,16666,5845,16669,5808C16670,5799,16666,5789,16660,5785C16655,5782,16650,5770,16650,5760C16650,5747,16645,5743,16635,5746C16626,5750,16620,5746,16620,5737C16620,5717,16549,5667,16495,5649C16473,5642,16451,5632,16446,5628C16440,5624,16426,5620,16413,5620C16395,5620,16390,5615,16390,5593C16390,5577,16381,5552,16371,5536C16351,5506,16351,5482,16371,5367C16383,5300,16383,5298,16354,5242C16338,5211,16321,5182,16317,5179C16282,5154,16269,5063,16294,5016C16302,5000,16306,4972,16303,4946C16300,4920,16302,4900,16309,4896C16315,4892,16320,4881,16320,4871C16320,4849,16350,4820,16373,4820C16382,4820,16390,4816,16390,4810C16390,4795,16442,4799,16464,4815C16475,4823,16496,4830,16511,4830C16541,4830,16580,4870,16580,4899C16580,4908,16586,4924,16594,4935C16601,4946,16613,4980,16620,5010C16628,5040,16642,5081,16651,5101C16661,5121,16675,5159,16681,5186C16688,5213,16710,5278,16731,5332C16752,5385,16772,5446,16775,5467C16787,5539,16790,5550,16803,5547C16815,5545,16816,5554,16804,5630L16797,5675L16817,5651L16837,5626L16854,5658C16866,5682,16868,5695,16860,5709C16855,5720,16850,5749,16850,5773C16850,5797,16845,5832,16839,5851C16825,5895,16786,5979,16780,5980C16777,5980,16768,5970,16760,5958Z" stroke-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); stroke-opacity: 1;"></path>
If I add it manually via firebug etc to change the start to look like this:
<path transform="translate(0,239) scale(0.016963,-0.016963)" fill="#ff0000" stroke="#ccc6ae" d="
then it works perfectly. I just cannot replicate this.
I have tried various ways of adding the transform, but none have worked fully.
From what I gather, RaphaelJS is backwards compatible so all of the solutions I have found (which haven't fully worked anyway) wouldn't have worked in any older IEs for instance.
The first thing I tried was to change:
paper.setViewBox(0, 0, w, h, true);
to:
paper.setViewBox(true);
However this did not work with the shapes I am using (http://upload.wikimedia.org/wikipedia/commons/9/95/Continents.svg)
This is where I got the transform amounts from (can be seen if you view source).
Please advise on where I'm going wrong, and how I could go about adding this.
Many thanks!
---------------------------------EDIT -------------------------------------
After applying the fix below, I have found it appears to be displaying the SVG rotated 180degrees and flipped horizontally. I don't quite understand why either.
This is how it is meant to look:
And this is how it comes out:
(also noticed I'm missing south america despite it being referenced)
This is a new fiddle of how it currently looks:
http://jsfiddle.net/wrayvon/m7t4X/3/
Thanks again
The transform should work, but I think you just need to set a bigger width/height for the viewBox. These should be for the co-ordinate space, not for pixels on screen.
var w = 15000;
var h = 25000;
paper.setViewBox(10000, 0, w, h, true);
Should do it. You can also transform it if you want, by adding something like the following to the element when created.
.transform('t2000,1000')
edit: As you have changed the SVG... If there are transforms in the original, you will probably need to apply the same transforms to the elements...so a line like this...
var c = paper.path(worldmap.shapes[country]).attr({ stroke: "#ccc6ae", fill: "#ff0000", "stroke-opacity": 1 }).transform('s1,-1,13000,10000');
I'm just guessing the centre point to scale from there (13,000,10,000 its probably a bit more), you will need to figure that separately.
Or you could match the scale as per the original SVG, and then you probably won't need to change the viewBox (apart from matching the original).
Original jsfiddle
Updated jsfiddle
I have had success with the exact same problem. Your question is the clearest articulation of it.
As a bit of background, I found an SVG map of the US and all of its counties. I thought, "great, I'll just copy these paths into Raphael, and Bob's your uncle". So, I did, but it appeared exactly upside down after the import. I considered applying some math to the paths, but decided against it. Instead I investigated the transform() option too.
In the transform method, there are a few options. One of the options is to use the matrix ("m"). The matrix method has 6 options. - see here
for more details. But the matrix setting for the 'as-the-path' dictates is this:
.transform("m1,0,0,1,0,0");
If you make the 4th place negative, it will invert your image.
.transform("m1,0,0,-1,0,0");
HOWEVER...it has to choose a location for the axis on which to flip. That, as far as I can tell, is the top edge of the the container div. So your image is now above you. Use the viewbox to find it and zoom as you desire:
R.setViewBox(x,y,x-size,y-size);//The Y (second param) will need to be negative.
Here's my example to find my shape: (make your 200's into 1000's to more easily locate you image, then play with the numbers to center, and enlarge)
R.setViewBox(0,-575,200,200);
The downside using the transform is the overhead of drawing, then relocating the images. In my case, I am less concerned about this as speed doesn't seem to be affected, which may be due to the relatively small number of paths involved.

Creating an SVG Document in SVG.js issue?

I am new to SVG.js and javascript in general, and I was going over the documentation here http://documentup.com/wout/svg.js#usage/svg-document and was having some issues.
Usage
Create a SVG document
Use the SVG() function to create a SVG document within a given html element:
var draw = SVG('drawing').size(300, 300)
var rect = draw.rect(100, 100).attr({ fill: '#f06' })
so I was assuming from this they want us to call a function so what I've gathered from messing around a little in Three.js is that I need to do
<script>
function SVG()
{
//Use the SVG() function to create a SVG document within a given html
var draw = SVG('drawing').size(300, 300)
var rect = draw.rect(100, 100).attr({ fill: '#f06' })
}
</script>
within the body tag. This doesn't work however. When calling SVG(); I get an error
Uncaught RangeError: Maximum call stack size exceeded (15:22:47:898 | error, javascript)
at SVG (:18:13)
at SVG (:20:12)
at SVG (:20:12)
at SVG (:20:12)
at SVG (:20:12)
at SVG (:20:12)
There are other ways I can do it as mentioned, but it seems that the easiest method would be to call a function, but again I'm not sure if I'm doing this correctly.
I have a background in Java, just getting off of a project with JMonkeyEngine, so I'm not new to programming, but confused with what exactly I need to do with this, since the documentation is extremely vague and seems to suggest that you need to understand their terminology as to where to put the code.
I have also found a few other librarieslike snap.svg, d3, and raphael
http://d3js.org/
raphaeljs.com/
snapsvg.io/
I'm really just trying to create a bunch of pictures/colored boxes (interchangable so essentially a box with an image that can then be turned off and be displayed as a color) with borders, that can respond to mouse even of clicking and dragging around on desktop and mobile browsers. Essentially not much, but it seems like these all have similar features just a different coding feel.
Any advice?
Thank you everyone!
As said by Nils, there is a Hello World example here: https://stackoverflow.com/tags/svg.js/info
You also find plenty of documentation and examples to see what you have to do.
//Use the SVG() function to create a SVG document within a given html
var canvas = SVG(idOfElement)
// now an svg was created in the element with the id
// draw a rectangle
canvas.rect(100,100)

ImageOverlay and Rectangle Z index issue

I have a function that adds an imageOverlay and a semitransparent Rectangle on top of that image (so as to tint the image, and draw a keyline around it).
activeUserImage = new L.imageOverlay(imageUrl, imageBounds).addTo(map);
activeUserTile = new L.rectangle(imageBounds, {stroke: true, color: "#ffffff", opacity:1, weight: 1, fillColor: "#003572", fillOpacity: 0.7, clickable:true}).addTo(map);
this works great, but then I want to remove the image and rectangle with:
map.removeLayer(activeUserImage);
map.removeLayer(activeUserTile);
This seems to work well...
However when I try and add a second Image & Rectangle (using the same function) the rectangle SVG is being rendered underneath the image, so I don't see the colored overlay.
This seems to be because the element is being left behind from the first creation, and then when the image is being added a second time it appears in front of the SVG.
Q:
Is this a bug? Should the SVG element not be cleared too?
Can I adjust z-index of the image or SVG on creation?
should i be containing to rectangle in a different layer to the images? How?
Many Thanks
OK, so the Leaflet bringToFront() method didn't work, but instead I have used a bit of JQuery to force the same approach.
svgObj = $('.leaflet-overlay-pane svg');
svgObj.css('z-index', 9999);
This works, but still feels like a hack... however if (?) there is a bug in LEaflet, then maybe this will have to do???
Any better ideas?
The bringToFront() function alows you to bring layer to the top.
Search it in the docs.

Resources