display all elements in svg in a fixed area - javascript

I have some javascript code that dynamically creates SVG polygons at various locations. Currently if a polygon is created outside of the range of the SVG element's width and height, then it isn't displayed. I would like the polygons to scale down so that each polygon is visible, within the specified area.
As an example this only displays one triangle:
<svg width="100" height="100">
<polygon points="0,0 0,100 100,50 " fill="blue"></polygon>
<polygon points="100,0 100,100 200,50 " fill="blue"></polygon>
</svg>
but I would like it to display something closer to what this displays (two triangles scaled to fit inside a 100 by 100 box,) without having to change the points myself:
<svg width="100" height="100">
<polygon points="0,0 0,100 50,50 " fill="blue"></polygon>
<polygon points="50,0 50,100 100,50 " fill="blue"></polygon>
</svg>
This seems like it should be easy to do but I searched for "svg scale to fit" and "display all elements in svg in a fixed area" but I couldn't find anything related to my problem

Related

how to create d3 radial with dynamic radios

I created a radial with two tiers of options. I did in a way that isn't really dynamic and isn't really responsive to screen size. I now need it to be both of those things. Here is what it looks like when on the screen size I designed it for.
I created a working demo on sandbox that has the dimensions set how I need to use it on. This is what it looks like.
Here is link WORKING DEMO
any help is appreciated. Also keep in mind the outer tiers can have less or more options. it would be great if the blue toggle button would always align at the bottom of the radial like under the En of Energy Loss
I would consider using an SVG ViewBox in order to maintain consistency. What this basically does is create a consistent scalable SVG, mapping the size and coordinates of its container into a consistent range inside the SVG.
For example:
<div height="400px" width="400px">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="100%" height="100%" stroke="red" fill-opacity="0"/>
<circle r="4" cx="10" cy="10"/>
</svg>
</div>
So it basicalley creates a mapping from the 400x400 dimensions of the div, into the 100x100 of the svg, so the circle positioned at (10, 10) inside the svg will actually be in coordinates (40, 40) of the div

Why transforms shift the whole cordinate system instead just moving the element in SVG?

I have seen transforming the graphic in SVG don't affect the object to be transformed but transform the whole coordinate system and then draw the element in that system.
What does this help to achieve instead calculating the new cordinates for current element in consideration?
I think in canvas and CSS, its same behavior so tagging javascript and CSS also.
I am not sure I understand your question, but let me try:
The transformed element may not be a grafics element, but a container, for example a <g> element. In that case, all child elements inherit the transformed coordinate system.
The element may have associated paint servers (a pattern or a gradient, for example), or filters, masks or clipping paths that have their own sizing and positioning mechanisms. These mechanisms work in the transformed coordinate system.
Here is an example to illustrate. The first rectangle has a linear gradient, whose gradient vector is defined in user space. The second rectangle is identical, but rotated and translated to the side. The gradient is then moved together with the rectangle.
<svg width="200" height="150">
<defs>
<linearGradient id="gradient" gradientUnits="userSpaceOnUse"
x1="0" y1="50" x2="100" y1="50">
<stop stop-color="red" offset="0"/>
<stop stop-color="blue" offset="1"/>
</linearGradient>
</defs>
<rect x="0" y="20" width="100" height="30" fill="url(#gradient)" />
<rect x="0" y="20" width="100" height="30" fill="url(#gradient)" transform="translate(200, 20) rotate(90)" />
</svg>
While the transform attribute only takes userpace coordinates, i. e. unitless numbers, positioning and sizing attributes like x, y, width and height etc. may have unit identifiers like percentage, em or other CSS unit identifiers. That makes it possible to do more versatile positioning.
For example, the following rectangle will always appear at the same size in the middle of the SVG, regardless of it being resized:
<svg width="100%" height="100%">
<rect x="50%" y="50%" width="60" height="60" transform="translate(-30, -30)" />
</svg>

lock element to the SVG element

I have the following SVG of a phone:
<svg width="897px" height="452px" viewBox="0 0 897 452" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<g id="iphone" sketch:type="MSLayerGroup" stroke="#7E89A3" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M130,257.964 C130,266.797 122.809,273.956 113.938,273.956 L16.063,273.956 C7.192,273.956 0.001,266.797 0.001,257.964 L0.001,16.073 C0.001,7.24 7.192,0.081 16.063,0.081 L113.938,0.081 C122.809,0.081 130,7.24 130,16.073 L130,257.964 L130,257.964 Z"
id="bezel" stroke-width="2" fill="white" sketch:type="MSShapeGroup"></path>
<rect id="screen" fill="#ddd"
sketch:type="MSShapeGroup" x="9" y="36" width="111.93" height="199.084"></rect>
<path d="M77,25.746 C77,26.381 76.561,26.893 76.02,26.893 L55.918,26.893 C55.376,26.893 54.938,26.38 54.938,25.746 L54.938,23.166 C54.938,22.531 55.377,22.019 55.918,22.019 L76.02,22.019 C76.561,22.019 77,22.532 77,23.166 L77,25.746 L77,25.746 Z" id="speaker"
sketch:type="MSShapeGroup"></path>
<circle id="camera" sketch:type="MSShapeGroup" cx="66" cy="12" r="3"></circle>
<ellipse id="lock" sketch:type="MSShapeGroup" cx="65.04" cy="254.001" rx="10.04" ry="10.001"></ellipse>
</g>
</svg>
Which looks like following:
I will be using AngularJS to dynamically generate <ul> with elements on the phone screen, where generated elements will be interactive (users will be able to e.g. click on them).
The challenge however is, how to lock the size of my div element (which will hold the ul element), so that it always has the size of the screen? I want this phone to be center aligned on my page, but as far as I know, the SVG size will adapt to the actual window size.
Is there a way how to dynamically poisition my div element to be only on the phone's screen?
P.S. I can see that my SVG contains element with id screen so maybe somehow detect the position of this element?
I would recommend placing an absolutely positioned div over the SVG element. You can calculate the dimensions of the screen image by using the getBoundingClientRect() method. The code is simple:
var ui = document.getElementById("ui");
var screen = document.getElementById("screen");
var dimensions = screen.getBoundingClientRect();
ui.style.left = dimensions.left + "px";
ui.style.top = dimensions.top + "px";
ui.style.width = dimensions.width + "px";
ui.style.height = dimensions.height + "px";
You can see a working example here: https://jsfiddle.net/hxe9nb3n/
For a start it doesn't have to adapt to the size of the window. That behaviour is under your control.
Alternatively, you can embed HTML inside an SVG using the <foreignObject> element. That way the embedded HTML will adapt to whatever size the SVG becomes. There are many examples of how to do that in SO.

Svg polygon rounding

I am working on an application that is using svg move/rotate/zoom functionalities. I'm programming the back-end in Laravel and the front-end is using html/css/javascript. I've seen on the web that is possible for a polyline to have some sort of cubic-bezier to it.
Now my question is: is it possible for a polygon svg element to have the same cubic-bezier to it as the polyline like in this example?
The structure of the svg looks like is:
<svg>
<g data-type="track">
<polygon class="track" points="2588,851 2537,1157 1796,916 1117,723 0,382 40,80 816,314 1885,638 1887,634"></polygon>
<polygon class="track" points="114,19 73,0 17,497 46,485"></polygon>
</g>
</svg>
Is it possible to give the polygon element a cubic bezier so that it can create a fluid polygon instead of the square no-rounded polygon?
I think some of the responses here have been a little confusing.
(is it) possible for a polygon svg element to have the same cubic-bezier to it as the polyline
The short answer is no. <polygon> (and <polyline>) elements are always rendered as a sequence of straight line segments between the coordinates you provide. There is no way to automatically make the joins have a radius - like an HTML border-radius. If that is what you are asking.
If the line has a bigger stroke width, you can choose to round the outside corner of the line joins.
.track {
fill: none;
stroke: black;
stroke-width: 20;
}
.round {
stroke-linejoin: round;
}
<svg width="300" height="300">
<polygon class="track" points="20,20 290,20 290,130 20,130"></polygon>
<polygon class="track round" points="20,170 290,170 290,280 20,280"></polygon>
</svg>
If you want to include bezier curve segments in your "line", you will have to use the <path> element instead. As was used in the example you linked to.
I suggest to put one duplicated figure above another one with just smaller stroke-width. Profit! :)
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<polygon points="50,30 55,50 70,50 60,60 65,75 50,65 35,75 40,60 30,50 45,50" stroke-linejoin="round" stroke-width="50" stroke="red"/>
<polygon points="50,30 55,50 70,50 60,60 65,75 50,65 35,75 40,60 30,50 45,50" stroke-linejoin="round" stroke-width="30" stroke="#fff"/>
</svg>
A polygon does not use cubic Bézier curves, a path does. The example linked does not use any polygons, but a path which includes such curves.
The difference between a polyline and a polygon is simply that the latter is closed, so you can simply create a path and close it (implicitly or explicitly).
Beyond that, I'm not sure what your actual issue is.

Convert svg box to a css3 rotated div

I used a vector program to draw and rotate a box shape and the exported it as a svg file.
My goal is to read this svg data with javascript and use it to create a matching div. The div should be absolutely positioned and rotated with css3 to match the shape, position and angle of the svg box.
This might be quite a challenge (at least for me) so I'm not sure what would be the best way to approach the task. The svg code looks like this:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="800px" height="600px" viewBox="0 0 800 600" enable-background="new 0 0 800 600" xml:space="preserve">
<rect x="172.5" y="154.5" transform="matrix(0.8779 -0.4788 0.4788 0.8779 -68.2383 143.3385)" fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" width="149" height="102"/>
</svg>
I imagine the rect x and y values can be used directly to define the width and height of the div. But how to determine the correct rotation value for css..
SVG transforms are equivalent to -x-transforms using matrix(). Basically you want to take the SVG matrix and add commas.
So your SVG transform up there is equivalent to:
-webkit-transform: matrix(0.8779 ,-0.4788 ,0.4788 ,0.8779, -68.2383,143.3385);
http://jsfiddle.net/8P76p/
(Incidentally, that's not a pure rotation, it's a rotation + translate.)

Categories

Resources