Create SVG elements from collection without explicitly setting coordinates - javascript

I'm new to SVG, so I don't know if I'm missing something obvious and simple.
In every lesson on creating SVG elements, x and y coordinates must be explicitly set for element to be drawn. But is there a way for a browser to draw one svg shape right next to another, without explicitly specifying coordinates, like DOM does when you write <div>content1</div><div>content2</div>?
What I want is:
Having a collection of data for elements (let's say, they are all rectangles with only width and height specified), is there a way to draw all of them sequentially in a row (horizontally)? I don't want to manually set coordinates for each element, just call foreach element in array and expect browser to figure out coordinates from each element's width property.
Is this achievable only with some script that dynamically calculates bounding box for each element or there is some simpler way?

Related

Replacing SVG element (path) keeping same size/coordinates

I need to replace part of SVG image (map of hall seats) and it doesn't work as I would expect.
I have <g transform="translate(383.25,-48.882672)"><g .. node containing few rect and path elements which build an icon. I can find g by class with jQuery and .html(other_path_content) which makes content appear in the original size (too big to fit the original item spot). When I resize new icon <path d=.. manually and html it again, it goes off the place and appears in different location than original icon.
The problem here is that SVG images I get are random so I can't calculate place of the original icon and transform it to be there as it will be different everytime.
Is that possible to somehow calculate position of the original element and its size (mind it contains of few rects and pathes) and put new one on exact same place? Or maybe I'm missing something in my approach (do I need to re-init svg after appending new node etc.)?

How to apply parent transforms in the same order to child elements?

In my application users can select 3d objects on a workplane in order to scale, move or rotate these elements together using a "transformation" container, i.e. an Object3D, that groups all transformations and applies these to all children. When deselecting the child elements, the parent container's transformation should be transferred to all children which in turn are removed from the transform container and added back to the main scene object.
However, the child elements are transformed differently when in the transform container where the transformation is applied to the container and not the element itself, e.g. when applying a scale transform to the container with a child having a local rotation then it looks that the local rotation is applied first and afterwards the container's scale transform.
When applying parent's transformations to all children with child.applyMatrix(parent.matrixWorld) and putting the child back to the scene container the transformation order is reversed.
container[scale]{child[rotation]} -> order: rotation, scale
child.applyMatrix(parent.matrixWorld)
child[scale,rotation]{} -> order: scale, rotation
What would I have to do with the child elements to get the same transformation order and appearance result?
Update:
I figured out how to correctly apply the parent's transformations to the child. I used the same code from Object3D.applyMatrix():
child.matrix.multiplyMatrices(parent_old.matrixWorld, child.matrix); but also set child.matrixAutoUpdate = false; and left out child.matrix.decompose(child.position, child.quaternion, child.scale);
Therefore, matrixAutoUpdate = true does not work. Matrix4.decompose() somehow changes the matrix values before setting position, scale and quaternion thus in my example case the shearing transform of the inner child applied by parent's scale transform is reset.
To me this looks inconsistent since such kind of transformation is allowed and displayed when nested object transformations are used. Furthermore, using child.applyMatrix(parent.matrixWorld) to apply parent transforms to a child object (what I have quite often read as a solution for that purpose) would not be correct. I don't know if this is an intended behavior of three.js. If so, can someone explain why?
Thanks to #WestLangley and the provided THREE.js post and SO answer I figured out a solution for me. The issue I experienced is due to THREE.js' design concept of
representing an object's transform with a position, quaternion/rotation, and scale -- applied in the order S-R-T.
Simply put, when applying a non-uniform scale on an object's parent this order is changed and cannot be mapped from an object's transform matrix back to the convenient position, scale and quaternion properties.
My solution is to
represent the object transform with a matrix only.
That means that I set my 3d objects' matrixAutoUpdate = false and do not use the mentioned position, scale, quaternion properties anymore. Instead, I set any transformations on the object's matrix directly by utilizing THREE.Matrix4 methods only.

Google Chart API - How to access chart components at a specific position in Google Charts?

Usually you have event handler which catch mouse move or click events and give access to the element laying under mouse (a series or a cell) and a position (x, y). But in my case I have a screen point (x, y) need to access chart element it is targeting (if there is any).
In traditional way (Windows forms) there is a method like this ElementAt(int x, int y) in chart class and return value is an object like label, series, point, marker, ... etc.
The Google Visualization API does not expose any method to get the element(s) at a given set of coordinates.
Some of the charts support the ChartLayoutInterface, which allows you to get some information about the chart elements. You can use the CLI's #getBoundingBox method to get the top and left edges (relative to the chart container) and height and width of a given chart element. If you parse over all of the chart elements, you can get positions for all of them, so when you need to compare screen coordinates to elements, you could find the elements at the coordinates.
Unfortunately, there is no good way to get a list of all of the chart elements, so you would basically have to write functions that iterate over all possible elements in each element type until you fail to find one.

How do you change the sprite position in a animation? KineticJs

I the speech bubbles to be next to the person who says them but how do I change the position? I don't want to have any more animations for that, is it possible?
link: http://www.tlu.ee/~kristo93/Eritamine%20-%20puhas/p6hi.html
for example the next tere would be positioned next to the students.
There is always an X-Y co-ordinate of any group or element you create using the kinetic.js
You just need to manipulate X-Y property of the group containing your speech cloud.
suppose your reference to that cloud group is called cloudGroup then set the X and Y property using the method as follows:
cloudGroup.setX(100);
cloudGroup.setY(100);
So just insert anything instead of 100, which suits the position you desire.

Get Line co-ordinates in Javascript

I am drawing lines using Canvas (HTML 5), since lines/shapes are not stored as objects in Canvas, I cannot attach unique events to it (eg onmouseclick)
I wish to attach a onmouseover event to a line, is it possible by getting to know if the mouse if over a particular line (using its 2 X and 2 Y co-ordinates) in Canvas using Javascript. Would this work for different line widths (eg: 2,5 pixels)
Want to avoid using SVG as the entire project is built on Canvas
Please advise.
You would need to use math formulas to calculate the area of the line and whether a certain point intersects with it.
Here's a basic example:
Find mouse coordinates relative to position of the canvas (How to find mouse pos on element)
Calculate whether mouse x/y is inside some rectangle (Point in rectangle formula)
Done.
There is a function isPointInPath(x,y). It will return true if a point is on the current path.
You will have to call that for every line you want to check and the best way to do that is at the same time as you draw.
The best way is using some canvas frameworks. Look at "LibCanvas :: Creating Lines" (dont forget to dblClick at canvas)

Categories