I'm just learning details about the SVG viewport and viewBox. What I find confusing is, that it seem counter-intuitively, despite all positive x and y coordinates going left to right and top to bottom respectively in web design, the viewBox coordinate system seems to go right to left, and bottom to top respectively?
Am I understanding this correctly, and does anybody know why this is the case.
Thanks
This is not correct. viewBox declaration is x, y, width, height. And the origin 0,0 is top left - like most coordinate systems. If you have an example that is different, then it may be that there is a transform being applied at some level of your doc or CSS that is changing behavior.
The penny has dropped now. Because you move the viewBox to the right and down it creates the illusion that the graphic is moving to the left and up.
Related
I am using Inkscape to make a template SVG which I extract out the rect coordinates to use for my own drawing program.
I've noticed that Inkscape, when in landscape mode, adds a translate(0,-308.2677) to the group g element and then each rectangle rect element has a corresponding translate(0,308.2677).
My guess is that this is added (in A4 mode 308 is 'height - width' in portrait) in order to move the origin from top left to bottom left. So when a user of Inkscape swaps back and forth from landscape and portrait the bottom left is fixed with all items relative to that.
To me this seems a bit strange as Inkscape is an SVG tool and coords in SVG are top left growing x to the right, and y down.
My question is can I turn this off to force Inkscape to keep the origin at top left and not to dirty the SVG with extra translates?
Bonus: why does Inkscape do this? It is just aesthetics with the assumption that most people are Cartesian or is there a good programming reason for this?
thanks,
LB
is there a good programming reason for this
No. Not really. It dates back to the very early days of computer graphics and memory-mapped screen buffers. (0,0) was at the top left because that was the lowest memory location.
As time went on, that became the default origin position for most (but not all) computer OSs and graphics formats. And I am confident that was why the original SVG authors choose that arrangement also.
I suspect, as you do, that the Inkscape authors probably chose the normal cartesian bottom-left position because they though that would be more familiar to users. They are not unique among vector editing software.
Let me start out by saying my end goal is something that resembles the image below. It has 36 circles in each of the rings, spaced such that each dot is mid way between two dots in the circle inside of it
I figured out I could use a stroke-dasharray with really small lengths (.001 in my case) and stroke-linecap="round" to make the borders circular dots. The way I have it set up now each circle has a radius 5 bigger than the last and an incremented percentage for the stroke-dasharray. Here is my jsFiddle. Currently My inner most ring only has 21 dots and my outermost ring has 29 dots
How can I get the same number of dots per circle? Is there a mathematical way to do this or an attribute that I am unaware of? What can be done to evenly space out the circles using the whole circumference equally (instead of having some on the right side of the what I perceive as the x-axis)?
It seems to me that I would have to simply guess and check with the values in order to get it the way I want but I would love to be proven wrong. The stroke-dasharray documentation on Mozilla and W3C aren't very useful
Since you're using stroke-dasharray on a circle, you need to use π (3.14159265) to get even spacing.
Given the formula spacing = (radius × 2) × 3.14159265 ÷ numberOfCircles, your SVG circle would be <circle r="{radius}" stroke-dasharray="0.001, {spacing}"/>.
To achieve the spiral effect, apply a rotation of 360 ÷ numberOfCircles ÷ 2 to every other ring. I used CSS to accomplish this, circle:nth-child(even) being the selector and -webkit-transform: rotate( {rotation} ); being the style applied.
I forked your JSFiddle1.
1 Note that the spiral is visible in webkit browsers only. Also, the rings are slightly misaligned on the right for, to my knowledge, unknown reasons.
I'm using Raphael to draw the arcs as shown in the image below:
Z-index order is from lowest to highest: gray, blue, green.
Both the gray and the blue arcs start from the top, where the green one starts.
Is there any way to improve the edges? Especially the green over blue one.
Thank you.
I'm afraid there's not much you can do. How the shape is rendered depends on the viewer (browser, image viewer or importing application). You could play with the rendering properties and see if this gives you an improvement, but I believe hardly any SVG implementation supports them.
I am not sure exactly what you mean, and it is hard to know how you made the image without the raphael code. Are you talking about the way the outer edge of the green arc extends slightly beyond the outer edge of the blue arc? I would check that the corner points of the two paths are the same, and include the stroke-width in your calculations of the paths.
Perhaps you could try reducing the stroke-width to 0 to make things easier.
The problem is that you are overlapping the shapes. This causes some colors to spill out from underneath. To solve this you need to start each arc where the previous one ends.
You might get very faint gaps, this can easily solved by applying a 1px stroke to each arc.
I would like to identify the center of an SVG, so that I can manipulate multiple SVGs with ease.
I am trying to make multiple examples of the basic polygons (3 to 8 sides), and quickly realized that I either hade to make my own, which involves a lot of math, or I could pull from wikipedia the current ones. The problem with the former is that it takes a lot of time to translate the coordinates from Sketchup. The problem with the latter is that they are oriented differently and of different size.
I know that you can transform, scale, and rotate the SVG, but I need to know the coordinates of the center of the SVG. How do I find this out, so I can set universal manipulations?
Take the transform="rotate(degrees x y)", I need to know the center to accomplish this.
JS Fiddle
Here, I would like to set all the centers to the same, and then scale them to the same height and width, and potentially rotate them individually so that they all have a flat bottom, not a vertex.
The generic answer to your question isn't obvious...
It might be simpler for polygons, particularly convex polygons: you can iterate on the path and find its bounding box by computing the max and min of the x and y coordinates of each point of the path.
Then you can decide that the center of the shape is the center of the of the bounding box.
An alternative is to put an invisible element at what you estimate to be the center (for complex shapes, the concept of "center" can be variable), and get its coordinates to find out where the center is. Particularly for rotating purpose: you might want to do this rotation around a specific point which might not be the geometrical center.
I'm working on a UI which needs to work in different aspect ratios, 16:9, 16:10, 4:3
The idea is conceptually simple: Everything is centered to the screen in a rough 4:3 area and anything outside this portion of screen has basic artwork, so something like this:
(not drawn to scale)
Where the pink area represents whre all the UI objects are positioned and the blue area is just background and effects.
The trick is in usability, if I pass in coordinates (0,0) in a 4:3 aspect ratio environment (0,0) would be the top left of the screen. However if I'm in a 16:9 environment (0,0) needs to get renormalized based on the new aspect ratio for it to be in the appropriate place. So my question is: How can I achieve this?
edit: for clarification this is basically for a UI system and while I listed the ratios above as 4:3, 16:9, 16:10 it should be able to dynamically adjust values for whatever aspect ratio it is set to.
edit 2: Just to add more details to the situation: When the positions fo rsetting are passed in they are passed in as a % of the screens current widht height, so basically setting position x would be: [pos x as portion of screen]*SCREEN_WIDTH where screen width is the width of the current screen itself.
The obvious answer seems to be an offset. Since 4x3 is 16x9, it appears you want a 16x9 screen to have 2x9 bands to the left and the right. Hence, the X offset should be (2/16) * width.
For 16x10 screens, the factor is slightly more complicated: 4x3 is 13.33x10, so you have edges of width 1.67, and the X offset should be (1.67/16) * width = (5/48)* width.
So ... Can't you just come up with an abstraction layer, that hides the differences? One idea could be to model a "border" around the active area, that gets added. For 4:3 displays, set the border size to 0 to make the active area cover the full screen.