I need to render one element from an SVG to an image. It needs to be like it appears in the SVG, without further transforms.
The only way I can think of to achieve this, is to set the SVG's viewbox on the target element. To do this, I need to compute the element's bounding box relative to the SVG viewBox.
I've tried to use getBBox(), but I don't think it can work. Its coordinates are relative to the transformed element: the transforms of the element and its parents aren't applied. It's not possible to apply those transforms to the bbox since the transformed-bbox might not contain the object anymore: for example think what would happen if the bbox need to rotate by 45 degrees.
An alternative could be getBoundingClientRect(). However it represents the bounding box of the element relative to the screen coordinates and again it might not be enough to apply the transforms from the screen to the SVG viewport, since they could transform the bounding box in a way that breaks it.
The last idea I have is to create a new <svg> element (with no transform), place in it one (or more) <g> whose function is to apply all the transform from the original SVG's viewBox to the target element's, then place (a copy of) the target element into it and eventually call getBBox() on the newly created SVG element: if I'm not mistaken, the resulting bbox should be what I need and I can set it as the viewBox of the original SVG. Although it might not work if the target element contains some <use> elements or similar stuff. I think it'll take quite some time to implement this and I'm afraid it will be wasted time since it won't work for whatever reason.
Are there other ways to obtain an element's bounding box relative to the SVG viewBox? Otherwise other ways to correctly render one element from an SVG to an image?
Related
I have SVG paths that link up to elements (a bit like a rudimentary particles.js)
Each element is draggable and when this happens the path will follow the element wherever it goes but I would like the elements to animate without having to be dragged, and for the path to keep on following in the same way.
Is this feasible.
I have a javascript/nw.js project with an svg (referred below as svg-canvas) element that serves as a drawing canvas and inside it I have another movable svg element (referred below as svg-encapsulate) designed to encapsulate a dynamic collection of objects in a constrained space and whose size is therefore clipped using width and height properties. That way elements drawn inside that spill over its edges are clipped, so as not to appear to be spilling outside of the element. However, when I do getBBox on the svg-canvas, the BBox returns size that also includes clipped (invisible) elements inside the svg-encapsulate, which in turn triggers scrollbars for the entire element even when visually (from the perspective what user sees) everything fits. Is there a way to instruct getBBox to ignore clipped elements of the svg-encapsulate, so that one can maintain correct scrollbar behavior? Please note since svg-encapsulate can be resized, moved, and populated with various objects by a user, hardcoded margins and workarounds will not work in this case. Thanks!
after several days of researching and trying I want to see if you can help me.
I have a graph (coord) and students should mark the extrema of the graph. I have to use JavaScript for this and work in XHTML 1.0 Strict//EN. The idea was that the student clicks on the position on the graph where he/she thinks an extremum lies, this triggers a JavaScript function (addPoint) which adds an img into the same div in which the graph lies (coordDiv) and gives it the position where the student clicked. For an example visit http://ourresidence.net/JavaScript/ where you should be able to view both the site code and the JavaScript code.
As far as I understood, the positioning has to be absolute. static and fixed are incompatible with the desired behaviour and relative would be very difficult because 1. I don't know where the next "ordinary" positioning would be and 2. it would get more complicated with a student deleting a point. So, absolute it is.
Then the positioning should be absolute relative to the div coordDiv and after some time I even figured out how to give the div a concrete dimension (through it's a bit static, the approach with adjustCoordDiv() in klausur.js hasn't work out). However, if I resize the bounderies of the browser, the div and the graph wanders (since they are centered) but the point does not. That needs to be fixed.
And reading how mixed up the acknowledgement of zooming is in different browsers by now I've already completely given up handling zooming in the exercise, but if you come with a solution for that too, my praise would know no end.
Positioning is relative to some containing element in HTML that is positioned itself. If there isn't any such element, positioning is relative to document's body (as in your case). Positioning basically means to have applied some other position in CSS than static.
So you basically need to subordinate your click points to the DIV containing the whole coordinate system (as you do now ). That div should have
position:relative
without any repositioning to position it and to start a new "local coordinate system" for using
position:absolute
on any subordinated element.
On clicking, coordinates of that click need to be converted from global coordinate space to local one. This might be achieved iterating from clicked element to document element using properties offsetParent, offsetTop and offsetLeft of each passed element.
I want to place an svg precisely into the corner of a div. The svg has a dynamic generated stroke. If the shape of the svg is irregular or lets say a star, the distance to the outmost part of the border is hard to calculate.
The problem could be solved, if I would be able to get the dimensions of the svg including the stroke.
My idea is:
load the external svg
place it in the middle of the div
apply the desired stroke-width
get the outmost dimensions of the svg
place it in the corner
Can I get the width of the svg including the stroke? Any other ideas?
Thanks
getBoundingClientRect is the only way short of calculating it yourself from first principles. That method is only implemented in Firefox and IE9+ as far as I know though.
For example this returns 54 on Firefox.
I'm experimenting with the idea of making a web-based game with SVGs for graphics. I have one parent SVG element in my HTML file, and I dynamically insert SVGs loaded from other files with JavaScript. Internally, my game uses meters instead of pixels, and so pixel-wise, the graphics are quite large. Is there any way I can scale entire SVG elements? Or do I have to iterate through their graphical elements and scale them each individually?
In Google Chrome, explicitly setting currentScale doesn't seem to do anything; it's completely controlled by the browser's zoom level.
Set a viewBox attribute on the root svg element, that way you won't have to scale individual elements. Or leave them as is and allow zoom&pan. You can set a viewBox to show only part of the graphic too.
Without an example of how you use currentScale it's impossible to say if it's used correctly, but it should zoom the svg.