svg elements - scroll to/ centering - svg

I've an svg dynamically created on a page. As things "happen" (user clicks) the svg expands and collapses certain elements. It may fit in the viewport, it may not. In the case that its too big to fit on a page, the user must scroll to where s(he) wants to go/see. Now this is fine, however I have a requirement that the last element "selected" becomes the center of the page/viewport. i.e. If they click on an item, thats what they need to see without scrolling.
Could anybody tell me the best way to attack this. I've googled around but can't find what I'm looking for (though I'm not long at all this so I might have been searching the wrong stuff).
Is there a way to do this purely programmatically with javascript? Or am I obliged to pass by CSS to get the solution I want. Any tips/links/advice much appreciated.
thanks and have a nice day
G

I had a similar thing and I used the viewBox property to handle this. You could also use a wrapping <g> element, which you translate. However, from my point of view the basic approach is the same and you basically need to do two things:
keep track of the x and y offset and the dimensions of the viewport. (Using the viewBox will give you that »for free«)
Compute the center of the Element. Therefore I used the getBoundingClientRect()method which yields the AABB of of the Element in absolute coordinate space, relative to top-left edge of the whole page.
With these things, all that remains is to calculate the vector from the viewport center to the object's center.
Here you can find the reference of the viewBox and here a nice tutorial about it, because it can be a bit confusing at the beginning.
Another pro for the »viewBox« approach is: There is no dependency on special DOM elements, it just works on the root <svg> element. I once implemented both methods, I started out using a wrapping <g> element, what worked fine but gave me some performance issues. So I decided to change and use the viewBox, with the result, that the performance in Firefox grow, but slowed down in Chromium.
Edit
Here you can find a little fiddle, that outlines the approach. But be aware of the following: getBoundingClientRect() yields the position of the Element on the whole Page, so if your <svg> is not positioned at (0,0) (top: 0px; left: 0px), than that will include the offset of the svg itself. The offset of the viewBox must not include this offset, so you need to cancel that out somehow. For sake of simplicity I just used the client Bounding Rect of the SVG, what works because there are no transformations applied.

Related

Can I create a Calligraphy look with SVG?

is it possible to create a stroke with a dynamic width with SVG? I want to achieve a Calligraphy look like here, here or here.
Is this even possible? It seems customization of strokes in SVG is fairly limited. Even gradients in strokes seem to be non-trivial (see here).
There is a proposal to add into SVG standard a mechanism, that does exactly what you want:
http://www.w3.org/Graphics/SVG/WG/wiki/Proposals/Variable_width_stroke
http://lists.w3.org/Archives/Public/www-svg/2013May/0041.html
There's even an example implementation available here:
https://rawgit.com/birtles/curvy/master/index.html
It is, however, by no means official and we cannot be even sure it'll ever be.
Until then you'll need to stick to Bezier curves and object filling:
You can also use calligraphic fonts, for example - Tangerine available on Google CDN:
This approach requires less work since you don't need to draw everything from scratch, but then again, using third party fonts leaves you with little control over the final result.
You can't dynamically adjust the stroke of a path element. However you could draw a path, use a fill color on it instead of stroke, then double back upon the letters at a slight distance away from the original line.
Also, if you are using the SVG on the web then you can use css fonts on text elements. There are some pretty good cursive fonts that you can use for free... just check google web fonts.

What is the correct way to achieve intersection of multiple clip paths?

As described in another post, I am trying to recreate an SVG from vector graphics commands in a PDF and I am facing some difficulty in the part where I need to intersect a set of clip paths. For instance, the raw SVG has a few clip path elements line #16 which need to be intersected and applied on the rectangle fill (line #17) to obtain what looks like this: .
I am not clear about the correct and the best way to achieve intersection of multiple clip paths in an SVG. I wasn't able to find much information about this on the web except this one, going by which I came up with this SVG where I introduce a sequence of additional clipPath elements which try to intersect the current intersection with the next original clipPath to be added to the intersection set. This approach seems rather inelegant to me. Besides, that SVG doesn't seem to work on some versions of Firefox (ESR 17.x) though it renders the expected result on Firefox 5, Chrome and IE. Is there something wrong with the SVG? Or even if it is correct, is there a simpler/better way to achieve the intersection?
The way you've done it seens reasonable. There's a w3c example in the testsuite.

javascript raphael - how to stroke individual paths?

I am trying to make a tool for my website which traces over Japanese characters, showing the stroke order etc.. something like this: http://www.chinesehideout.com/tools/strokeorder.php?c=5pel
I have made a bunch of SVG files in inkscape, which are made up of just curves, one for each stroke of the character. I have then imported these into Raphael using the raphael-svg-import: https://github.com/wout/raphael-svg-import
The SVGs are displaying perfectly, however I want to animate them.
My question is: Is there a way to take each path from the SVG in turn in Raphael, and then animate/stroke them? If so..how??
If you need any more info please say!
Thanks
EDIT: Perhaps I should clarify, when I say stroke I mean progressively draw the line, starting from the first point and ending at the last. At the moment it draws all paths simultaneously and draws the whole of each path at once.
The technique people use in svg for doing this is outlined in this answer. It's probably possible to adapt that to Raphaël, though the Raphaël documentation doesn't list stroke-dashoffset.
Raphaël has a method Element.getSubpath(from, to) that can be used to get only part of a path, that should probably also be an option.

How to Scale SVG rectagle to fit the svg text element

So here is the problem:
I am trying to create dynamic buttons that have text. The text will be generated dynamically so the svg object doesn't know the size of the text. There are two things that I am looking to do and I hope that SVG will do this
First I want the left and right edge of the svg element to stay the same even if I scale the element horizontally
The problem is that I have to set a width on the svg otherwise it doesn't show up when I display the page. Also on the Home and blog buttons you can see that the edge is compressed. I want the edge to stay the same no matter how much text is in the element.
Also I can't seem to set the scale or width properly even with a javascript .getComputedTextLength()
Any help or a point in the right direction would be very helpful
Buttons that are sized to their text content is functionality that can be adressed with Raphael's getBBox()
The use of this js library means that you are implicitly using SVG or VML and this functionality is more easily addressed by referencing this JavaScript library
To see the getBBox() function in action you could visit the Autobox example here:
http://www.irunmywebsite.com/raphael/additionalhelp.php?v=2

resize and draggable the group of the SVG element

I am working on a SVG application and now want to let a user resize an object using draggable corners, very much like in SVG-edit (http://svg-edit.googlecode.com/svn/trunk/editor/svg-editor.html).
The functionality should work as follows: The user selects an SVG object, drags it to the main ‘canvas’ and once on the ‘canvas’, four corners on the outside of the object appear, the user can drag on each of the corner points & drag to enlarge the object. The objects will be rectangular in shape and created using paths, not using the SVG ‘rect’ function.
Would anyone have any suggestions as to how this should be implemented?
Thanks in Advance
You could take a look at some existing open source implementations. svg-edit is one which you already mentioned.
To showcase a tool that I developed, I wrote a demo which implements this functionality. This which may serve as a simpler and more restrictive example than svg-edit, as it doesn't do too much other than allow you to draw rects and circles, and rotate/translate/scale them.
I have edited jquery to make rect draggable, recently put them in a g and lost this functionality. The g doesn't contain the position data.
Might be possible to bubble down to the children elements.

Resources