How to create CSS/JavaScript circles grid - javascript

I need to do something like this:
This may look quite easy, but there are some requirements:
- the width of the containing div should depend on the text length (is it possible at all in CSS?)
- all circles should be positioned randomly - this is the most diffucult part for me.
As I'm using border-radius for creating circles (setting height, width and border-radius of 50%) I try to create some kind of grid in JavaScript where I iterate through each element and get its dimensions. Then I get the position of previous element (if any) and add them to the current element dimensions. Additionally, adding some margins will help avoid collisions. Is it correct approach?
I'm just looking for a suggestion how to solve my two issues.

Circles that scale based on size of content.
This is something you will need to solve first, because you wont be able to place them anywhere without first knowing their dimensions.
Naturally the size of a DIV expands first by width, then by height. That is, the maximum width of a container must first be utilized before moving on to the height constraint. Because of this, making a circle scale with equal radius may prove to be quite difficult without using a relative averaging.
Relative averaging is finding the average dimensions of your height / width based of the exhisting area of the contianer bounding your content. For example:
The width and height of the DIV bounding your content can be detected with javascript. Let's say youve discovered those properties too be 200px x 20px respectively.
Your total area is width * height so 4000px; But we are trying to acheive a square so we can apply rounded corners and form a rounded circle. We want to find dimensions of a rectangle that will be equal to the same area and then apply those new dimensions.
To acheive the same area with an equal width * height you can do something like:
√ 4000 = 63.2455532
Thus: 63.2455532 x 63.2455532 = 4000
Random placement of DIVs, and avoid collisons between DIVs.
After finding dimensions, you will be able to use a rand on your (X,Y) coordinates for the placement. Push these coordinates and radius onto an array. Use recursion too place the remaining circles on collsion failures. A collision failure would come from an element that has overlapping (X,Y)+radius relative too elements in the array that were pushed successfully.

Related

How to get width of the image with non zero rotation (konva)

I have an image inside Group element. With Transformer element, user changes image width and rotation. After that, how do I get image width? getWidth() returns the value which I manually have set while creating new Image. getClientRect().width returns the actual width, the way it displayed for the user, so it seems ok, but the problem with it starts when the image is rotated. Because the getClientRect().width returns not the image width (y), but the width of circumscribed rectangle of our image (x)
I'm using Konva v7.0
See Konva code tutorial re transformers here, image below. The width and height values do not change as the shape is 'stretched', but the scale values do change.
The intro to the transformer class in the Konva docs says:
Transformer constructor. Transformer is a special type of group that
allow you transform Konva primitives and shapes. Transforming tool is
not changing width and height properties of nodes when you resize
them. Instead it changes scaleX and scaleY properties.
And I have seen in the Konva docs various mentions that the dimension methods do not take into account scaling.
In summary then, the transformer changes the dimensions of shapes it effects by scaling them. Therefore the current scaled width for a shape can be found by:
let visibleWidth = shape.width() * shape.scaleX();
If the shape in question is part of a group that is transformed then you will need to use
let visibleWidth = shape.width() * shape.getAbsoluteScale().x;
to get the absolute scale of the node which takes into account its ancestor scales.

Wrong position of absolute elements when browser zoom != 1?

I have a full screen div containing a map with absolutely positioned elements within it (cities, armies etc).
It all works fine with the default browser zoom, but if I change the browser zoom level, the positions change in seemingly random ways. Sometimes they're a pixel left/down/right/up with no rule I can figure out.
The absolute element positions are calculated based on their coordinates within the map, so for example if an element has coordinates x: 5, y: 8 and one map quadrant has dimensions of width=20px, height=20px, then its position is calculated as:
var pos={
"x": 5*20,
"y": 8*20
};
My best guess is that the browser is rounding off these pixel values when the browser zoom is changed. For example, if browser zoom==0.911 then the real quadrant size comes out to 18.22 x 18.22. If the browser rounds this value to 18.2 for example, then pos would be a few pixels off.
Is my assumption correct and is there a solution that will work consistently regardless of browser zoom level?
EDIT: one simple solution (that worked) was to structure the map as a table with fixed td width/height, but this creates an immense number of useless HTML nodes and slows down the load time of the page, which is unacceptable to the client. I need to keep the map as a simple div with just the absolutely positioned elements inside it.

How to set the scale value in pixel size?

How do I set the object scale value(width and height) based on the pixel value using three.js?
object.scale.set(0.05,0.05,0.05);
I need to set 0.05 value pixel size
Rephrasing your question, please correct me if I got you wrong:
You want to use pixel values instead of the relative values to set the size of your object as it appears on screen.
Now, the problem here is, that three.js (or even webgl) don't really use a concept of pixels internally.
How large (in pixels) an object appears on the screen depends on a lot of factors:
the css-size of the canvas element and the devicePixelRatio
the width and height of the canvas element
obviously the size of the object
the camera-position and other properties (aspect-ratio, field-of-view, relative orientation and position to object)
So pixels will simply lose any meaning when it comes to 3D-graphics. There's nothing keeping you from using any unit you want for sizes and positions, but that doesn't make it have any relation to pixels on screen.
You will also want to check out this answer: THREE.JS: Get object size with respect to camera and object position on screen

spread HTML elements randomly over a div using JavaScript

I wish to create something like a virtual forest.
I have:
fixed size div, where I wish to spread the trees
Random number of trees (each tree is a PNG)
small square div in the center that should be kept clear of trees
How can I spread the trees so they:
Wont overlap each other
Wont get into the central div
Calculate their size (css) so all trees will fit into the div
Thanks
More info as requested:
All the tree images has same dimension
Container div has a fixed dimensions of 500x300 px
Small central div has a fixed dimensions of 30x30 px
The png native resolution is 60x60 px
I created the following php script, but it does not handle the empty location nor its accurate in fitting the images into the div:
$forest1 = null;
for ($a=1; $a < 201; $a++) {
// width * height (500*280)
$total_area_in_pixels = 140000;
$total_elements = 200;
$area_per_object = $total_area_in_pixels / $total_elements;
$element_height = round (sqrt($area_per_object) / 100 * 70);
$random_margin = rand(0, $element_height / 5);
$tree_type = rand(1,4);
$style = "height: {$element_height}px; margin: {$random_margin}px;";
$forest1 .= "<img src='images/trees/tree{$tree_type}.png' alt='{$a}' title='tree' style='{$style}'>\n";
}
You need to figure out how you want to do the positioning first. You can either set the trees absolutely based on the div parent as a container, or you can position the trees absolutely based on the entire page as a container.
To use the parent as a container, you would do this:
Set the div to position: relative. Write javascript to create IMG elements and then set their position to 'absolute'. Make sure that when you create the elements you create them as child elements of the DIV you want to contain them.
TO use the page as a container, you would do this:
Write javascript to create IMG elements and set their position to 'absolute'. Don't bother making them child elements of the DIV because it doesn't matter. Use jQuery or a basic javascript test to find out the exact page position of the container div. Everytime you place a tree, you will need to calculate its position with respect to the container div.
Position trees basically like this:
Write a simple algorithm to generate random x and y coordinate pairs to position each element and do so. Then check each tree's position and width and height against the square area you don't want to be covered. If you find a tree in that area, either move it some to get it out of the area, or delete it. Just make sure to remember that if you're positioning absolutely within the whole page, you'll always have to add or subtract the page container position as an offste to get the trees where you want them on the page.
That should be enough to get you started.

box to keep proportion when scaling with javascript

I have made a script: http://jsfiddle.net/radar24/XZgh4/ which scales the given dimension into the outer div. everything seems fine, until I enter a dimension such as 200 x 99. then the box grows outside.
I really cannot find the cause of this, can anyone help?
The problem is that you're not restricting your proportions along both axes. Your box has a height:width proportion of 5:3. If you don't restrict along both axes, you can have bleeding outside of the boxes. An example might show this best.
Take the case of the height being the bigger of the two dimensions. Your code is only restricting it along the 500px axis. Consequently, if we throw a box in there with 5: >3 proportions, you get a creeping edge.
For instance, put "3" and "5" in your boxes. Fits perfectly. Now make it 3.1 and 5. Ruh roh.
You'll need to add another if statement in each section that THEN determines if the dimension ratio goes outside this boundary. In the above case, you'll need to make it so that the height of the 5:3.1 is not 500px, but rather, the height (less than 500px) that would make 3.1 to be equal to 300px. That would be 483px.
Does that makes sense?
If not, I'll try to rephrase again:
Put another set of if statements in the two if statements you already have. These check if, upon setting the LARGER dimension, it makes the SMALLER dimension go outside the bounds of the box in that direction.
in pseudocode
if (height > width)
calculate the height
calculate the width
if (width > div.width)
width = div.width
height = div.width * aspect;
Just ask me if this isn't clear enough!
Edit: Here's a JSFiddle that gets it right. You'll need to add further code if you want a white border along each edge.
Edit2: Here's the white border come back!
Edit3: You can also try prettying it up and using just aspects to do this. I did the first one for you. Three to go!
It's a pretty small mistake. You forgot to convert the width and height to integers before comparing them. So you would need to change if (width >= height) to if (parseInt(width) >= parseInt(height)).
jQuery .val() always return a string you should parse it into integer
changed jsfiddle
....
height = parseInt($('#height').val()) || 0;// making 0 as default value.
width = parseInt($('#width').val()) || 0;
....

Categories

Resources