Refresh svg coordinates on window resize - javascript

I'm new to SVG and I'm having trouble solving this problem :
I'm trying to create a system of points, rotating around a single axis, like a solar system.
The center point is a round div, placed to the center of the viewport with the help of the CSS calc function :
left: calc(50% - myDivWidth/2);
top: calc(50% - myDivHeight/2);
I placed SVG circles around this central point with the "cx" and "cy" attributes and everything works fine.
Here's the problem : when I resize the window, the div is automatically moved to stay at the center of the screen. But my SVG circles are not moving because the coordinate system doesn't stretch to the new size of the viewport. Now if I reload the page after resizing, everything is placed correctly again.
I thought I could recalculate the coordinates of my circles when a resize occurs but isn't it a bit heavy ?
All my circles are placed in a svg tag with a 100% height and width.
I hope you can help me with this ! Thanks !

If you add a viewBox attribute to your SVG, it will automatically be scaled to fit it's parent viewport (<div class="univers">).
<svg width="100%" height="100%" viewBox="-315 -315 630 630">
With this viewBox you can use (0,0) as the origin for your orbiting circles.
Demo here

Related

Fabric.js move background to center

I'm attempting to move the background image so that it's center is positioned in the center of the screen rather than in the top left corner. So far, this code attempts to center it but it's dependent on the size of the window and is inconsistent.
canvas.backgroundImage.left = -(canvas.backgroundImage.width / 2)
canvas.backgroundImage.top = -(canvas.backgroundImage.height / 2)
Any object in Fabric, including background images, can be centered with the center() method.
canvas.backgroundImage.center()
You can also call centerH() or centerV() for horizontal or vertical centering.
See http://fabricjs.com/docs/fabric.Object.html#center

How can I translate with webkit-transform enough so that

I am using webkit-transform: scale(zoomFactor,zoomFactor) in css to zoom the contents of an iframe. When I zoom it to the proper size to fit inside the iframe, the positioning of the elements is offset like this:
I cannot figure out how to find the x and y I would need to offset it to get it so that the contents of the iframe appear to be in the same corner as before it was scaled. The amount the contents are offset depend on how large or small the scalefactor is. Does anyone know how I can get this to work?
by using transforms you can set the transform origin.
In your case you want to scale to the top left.
so the origin should not be default (center) but at 0px left and 0px top.
-webkit-transform-origin:0px 0px;

Change the origin when resizing and moving an image

I am trying to make an image resizer and cropper, but am having trouble with resizing it from a desired point.
Currently, you can resize (just changing the with+height of an <img> element) and move around the image (offsetting the top and left margins of the <img> element). The problem is once you move it and resize it again, it does so from the center of the image. I would like it to resize relative to the center of the crop window.
Here is an image of what I currently have (top) and what it should be like (bottom):
http://i.imgur.com/eAE4IEF.jpg
I have been unable to figure out the math of how to resize it and then move it so the origin is not in the center of the image, but in the center of the red window.
I would appreciate any help with this.
This is essentially scaling an individual point inside the image (the center of the crop box) by the given scale factor, which involves multiplying each of the coordinates of the point by that factor.
new_center_x = old_center_x * new_image_width/old_image_width
new_center_y = old_center_y * new_image_height/old_image_height
http://jsfiddle.net/jDXHz/5/
You can then shift both the image and the box back by the difference between the new and old position to keep the box stationary while the image scales around it.

Raphael JS detect canvas size when set as %

I am using Raphael JS, and create a canvas with width set at 100% of the container like so...
// there is a `div` with id `paper`
paper = Raphael('paper', '100%', '100%')
paper.circle(50, 40, 100)
Now I want to know how big the canvas is. how can I reliably find out the canvas size on all platforms?
I am not using jQuery.
Update: Potential workaround
Bonus points will be awarded for a solution that makes getting pixel width unnecessary, by making cavas scale proportionally. I am fairly sure this is possible with canvas so assume it is possible with Raphael, so that if I create all elements to a set width (say 100 pixel wide canvas) then I should be able to scale the canvas to 100% of the screen, and the canvas should fill the screen, with all elements stretched appropriately, and keeping their proportions.
You can use the viewbox in order to scale to fit in full screen mode.
http://raphaeljs.com/reference.html#Paper.setViewBox
You define a physical region (x, y, width, height) that contains your svg data, and everything will be scaled up while maintaining the proportions. The viewbox region is upscaled proportionally (when you specify false for fit) to the maximum size it can be inside the container.
paper.setViewBox(0, 0, 100, 100, false);​
Unfortunately, Raphael doesn't seem to give you the option of specifying how the overflow is handled. For example, you might wish to centre the view box so that any excess is spread evenly. If you have a 100 x 200 container and you have a 100 x 100 viewbox, then you have 100 pixels in height below the upscaled viewport, when you may wish for the viewport to have 50 pixels above and 50 pixels below.
In SVG these options are defined on the SVG container's preserveAspectRatio property. If you are not supporting the VML (lte ie8) option then you could change this property to affect the alignment.
http://premsobel.info/notes/ml/svg/viewports.html
As for detecting width and height in general, you are better off detecting the width or height of the parent node using element.clientWidth and element.clientHeight. I tend to avoid using body as the parent node and add my own inner container for detecting the size. Your canvas is 100% width/height of some container, so I would go looking for that container to find out what size it is.

SVG / SVGPan: center graphic upon loading

I had been using nested <svg/> and <g/> elements to center an SVG graphic within my browser frame. The outer svg element had width and height of 100%, the inner had x and y set to 50%. An inner g element had negative offset of half image size. This was working fine but I now want to add pan and zoom functionality.
The nested SVG approach seems to be incompatible with SVGPan which gets confused.
SVGPan will only work if I start with the graphic at top-left. I think I'll have to write a script that runs when SCG is loading/loaded to add a transform to center the top-level g in a way that is compatible with SVGPan.
How can I initialize my <g /> with a matrix transformation that translates it thusly?
((viewport.width - g.width)/2, (viewport.width - g.width)/2)
The size of the viewport is not known when the SVG is created but I can drop some script in there to create the transform or translation. Where should the script live and what should it do? It needs to be compatible with SVGPan.
Talos solved this issue for me, see https://github.com/talos/jquery-svgpan/issues/3
Instead of
<svg><svg><g></g></svg></svg>
I'm now using
<svg><g><svg></svg></g></svg>
and that allows a centered graphic to work with [jquery-]svgpan.
To fill an SVG element in any HTML element:
Put position:relative (or position:absolute or position:fixed, if appropriate) on the wrapping HTML element.
Put position:absolute on the SVG element (and top:0; left:0; width:100%; height:100% if necessary).
With this your SVG element will always fill the HTML element. Position/size/center this element as desired.
To get your SVG content centered within the SVG viewport
Set the viewBox on your SVG to be centered around the center of your content.
For example, if your content is a circle of radius 30 centered at 175,300 then set viewBox="145 270 60 60".
Omit the preserveAspectRatio attribute on the SVG element, or ensure that it uses xMidYMid so that the center of the viewbox is always centered in the SVG viewport.
To pan and drag your SVG content
Adjust the viewBox accordingly, or else transform elements.

Categories