Display number of divs according to the window size - javascript

For example the below image is at initial window position..
When I will decrease the window size then the number of divs should change accordingly.
Edit : Each map represents a Div.

Get sizes of maps:
var maps = document.getElementsByClassName('.map');
for(var i = 0; i < maps.length; i++){
var map = maps[i];
var rect = map.getClientRects()[0];
map.left = rect.left;
map.top = rect.top;
map.width = rect.width;
map.height = rect.height;
}
On screen resize event, where you will check:
for(var i = 0; i < maps.length; i++){
if(maps[i].left + maps[i].width > screen.width ||
maps[i].top + maps[i].height> screen.height)
maps[i].style.display = 'none';
else
maps[i].style.display = 'block';
}
I have not tested, hope it works

With jQuery, use the .resize method to check whether the window has been resized, then calculate how many divs you want to display (which is the window size divided by your div size). To get window height and width:
var h=$(window).height(); // returns height of browser viewport
var w=$(window).width(); // returns width of browser viewport
You can use .hide and .show to nicely reveal the exact number of divs.

Related

Javascript scale images to fit container and to equal height

I'm trying to build a gallery. The idea is to fit images into fixed width container, but images must be of the same height and preserve original aspect ratio, so they just need to scale somehow.I came up with a solution of my own, but it, sometimes,gives clunky results for images total width that are too small or too large to fit container.Also resulting widths are, for some reason, floating point values. Could someone help me to figure out more optimal way to do it?
My clunky solution: https://codepen.io/fuzzy-toozy/pen/wvEaorW
function recalcGallery() {
if (uploadedImages.length > 0) {
let min = galleryHeight;
for (let i = 0; i < uploadedImages.length; i++ ) {
let currentUploadedImages = uploadedImages[i];
// find element with smallest height
currentUploadedImages.forEach((val) => { if (min > val.height) { min = val.height; }});
let imgCont = [];
let totalWidth = 0;
// set all elements to same height
for (let j = 0; j < currentUploadedImages.length; j++) {
let imgContainer = document.querySelector(`[image-index${i}="${j + 1}"]`);
imgContainer.style.height = `${min}px`;
imgCont.push(imgContainer);
totalWidth += imgContainer.clientWidth;
}
if (totalWidth > galleryWidth) {
// calculate value to decrease height by based on percent of overflow
let decPx = Math.ceil(min - min * (galleryWidth) / totalWidth);
imgCont.forEach((val, i) => {
val.style.height = `${val.clientHeight - decPx}px`;
});
}
}
}
}
Your solution involves finding the element with the smallest height, setting all elements to the same height, and then checking if the total width of the images is greater than the gallery width. If the total width is greater, you calculate a value to decrease the height by based on the percentage of overflow and then decrease the height of each image container.
One potential issue with your solution is that you are relying on the clientWidth property of the image containers to calculate the total width of the images. This property can include padding and borders, which may not accurately reflect the total width of the images. A more accurate approach would be to use the naturalWidth property of the image elements, which reflects the actual width of the image.
Here is an example of how you could modify your code to use the naturalWidth property:
function recalcGallery() {
if (uploadedImages.length > 0) {
let min = galleryHeight;
for (let i = 0; i < uploadedImages.length; i++ ) {
let currentUploadedImages = uploadedImages[i];
// find element with smallest height
currentUploadedImages.forEach((val) => { if (min > val.height) { min = val.height; }});
let imgCont = [];
let totalWidth = 0;
// set all elements to same height
for (let j = 0; j < currentUploadedImages.length; j++) {
let imgElement = document.querySelector(`[image-index${i}="${j + 1}"] img`);
let aspectRatio = imgElement.naturalWidth / imgElement.naturalHeight;
let imgContainer = document.querySelector(`[image-index${i}="${j + 1}"]`);
imgContainer.style.height = `${min}px`;
imgContainer.style.width = `${min * aspectRatio}px`;
imgCont.push(imgContainer);
totalWidth += imgContainer.clientWidth;
}
if (totalWidth > galleryWidth) {
// calculate value to decrease height by based on percent of overflow
let decPx = Math.ceil(min - min * (galleryWidth) / totalWidth);
imgCont.forEach((val, i) => {
val.style.height = `${val.clientHeight - decPx}px`;
val.style.width = `${(val.clientHeight - decPx) * (val.querySelector('img').naturalWidth / val.querySelector('img').naturalHeight)}px`;
});
}
}
}
}
In this modified code, we calculate the aspect ratio of each image using the naturalWidth and naturalHeight properties, and set the width of each image container accordingly. We then use the clientWidth property of the image containers to calculate the total width of the images, but we use the naturalWidth property of the image elements to calculate the width of each image container when we need to adjust the height of the images.
Note that this code assumes that the images are contained within an tag within each image container. If you are using a different approach to display the images, you may need to modify the code accordingly.

get mouse position inside resizing div using raycaster and vector

I am able to get the intersects from my click event when I use the window object to acquire height and width, but getting the intersects position on a canvas that's dynamically sized is proving much harder. I'm not certain of the formula I would need to use to calculate the vector.x and vector.y values with a div that isn't always the same size.
The canvas is the size of a div that always has a width: height ratio of 4:3 and resizes to fit in the window and is always positioned in the center of the window.
If I resize the window to be 4:3 then the following code works perfectly:
mouse.x = (ecx/div_width) *2 -1;
mouse.y= -(ecy/div_height) *2 + 1;
when I resize the window, whichever dimension is larger than the size of the canvas has the incorrect value. I've linked an image to roughly describe how the problem presents itself
Image of horizontal dimension issue
I initially thought that the matches would be as simple as dividing the difference between the the sizes of the window and the canvas by
My question is, how would I acquire the correct values to pass to the vector object for it's x and y attributes? (using Vector3 and Raycaster)
here is the function I'm using to try and get the object(s) being clicked:
function getClicked(event){
event.preventDefault();
var ecx = event.clientX;
var ecy = event.clientY;
//elem is the div containing the canvas
//the canvas is not the same size as the window
var elem_w = elem.innerWidth();
var elem_h = elem.innerHeight();
//most examples suggest using the window height and width
//to get the position of the mouse in the scene.
//since the scene isn't the same size as the window, that doesn't work
var ww = window.innerWidth;
var wh = window.innerHeight;
mouse.x = (ecx/ww) *2 -1;
mouse.y= -(ecy/wh) *2 + 1;
var objlist = []
rc.setFromCamera(mouse, camera);
var intersects = rc.intersectObjects(scene.children, true);
for (var i=0;i<names_to_spin.length;i++){
var obj = intersects[i];
objlist.push(obj);
}
//ideally, this should return a list of the objects under the cursor
return objlist;
}

Fill window with divs. Div pixel height displayed incorrectly in google chrome. Width works

I want to fill the window size with divs. For a specified div size in px, the screen will be filled as much as it can be, leaving a remainder edge amount of px on the side and bottom. This remainder amount is then divided by the number of cells in the row (or column) and that is then added to the height (or width) of each cell in the row (or column).
For the width this works perfectly but when the same logic is applied to the height, it breaks. Both width and height work in firefox.
Screenshot: http://i.imgur.com/mpDCM0G.png
JSfiddle of making the divs: https://jsfiddle.net/xb82c4zt/
Live: http://conwaygameoflife.heroku.com/
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var size = 100;
// Calculate the number of cells we can fit in the width
//and height (there will be extra space)
w = Math.floor(windowWidth / size);
h = Math.floor(windowHeight / size);
// Calculate the extra space
var widthDiff = windowWidth % size;
var heightDiff = windowHeight % size;
// Add the needed amount of height and width to each cell to fill the window
var widthSize = size + widthDiff / w;
var heightSize = size + heightDiff / h;
// Begin to alter the DOM
var parentDiv = document.createElement('div');
parentDiv.className = 'grid';
for(var y = 0; y < h; y++) {
for(var x = 0; x < w; x++) {
var cellDiv = document.createElement('div')
cellDiv.className = 'cellDiv'
cellDiv.style.height = heightSize + 'px';
cellDiv.style.width = widthSize + 'px';
parentDiv.appendChild(cellDiv)
}
}
document.body.appendChild(parentDiv)
In Chrome (and probably other browsers), height and width pixel values are truncated! See this stackoverflow answer with the related jsFiddle
Precentage values are truncated too, but not as severely. So, to solve this you can convert pixels to percentages as I did in this jsFiddle.
The main thing I added was:
var widthPercent = widthSize / windowWidth * 100;
var heightPercent = heightSize / windowHeight * 100;
Because we're using percentages now, the parent container must have width/height:
parentDiv.style.height = windowHeight + 'px';
parentDiv.style.width = windowWidth + 'px';
And changed the loop to:
for(var x = 0; x < w*h; x++) {
var cellDiv = document.createElement('div');
cellDiv.className = 'cellDiv';
cellDiv.style.height = heightPercent + '%';
cellDiv.style.width = widthPercent + '%';
parentDiv.appendChild(cellDiv)
}
Now this doesn't always work in chrome perfectly. However, it does make it perfect in some cases... basically depends on when (and how drastic) the truncation of percentages is.
After further reflection, it looks like percentages get resolved to fractional pixel values as well... which still get truncated in Chrome. So, let's make our math better, and figure out the biggest non-fractional pixel value we can use... it's actually really easy. See here
Basically, we just floor the values, then center the grid so that we can make it look nice.
edit: wasn't very happy with this answer, so screwed with it some more. Added a function that found the closest multiple of window size and made it so that it would prefer that number. Makes it work in most screen sizes, and has a fallback to the percentage method if it doesn't perfectly work. See here. However, because it relies on a recursive (naive) algorithm to find the closest multiple, it's really easy to screw your browser performance. Limiting to only 5-10 pixels of search space helps. The gist of it:
function closestMultiple(width, size, n, limit) {
if(n > limit) {
return {m: width/size, s:size};
}
if((width % (size+n)) == 0) {
return {m: width / (size+n), s: size+n};
} else if((width % (size-n)) == 0) {
return {m: width / (size-n), s: size-n};
}
return closestMultiple(width, size, n+1, limit);
}
It's very naive and ignores things like "an odd width will never be divisible by an even number"... so there's a ton of room for improvement. Check out this discussion and this discussion for more on this.

Detect percent on screen of an element

I'm trying to detect what % of the element can be seen on the current window.
For example, if the user can only see half the element, return 50. If the user can see the whole element, return 100.
Here's my code so far:
function getPercentOnScreen() {
var $window = $(window),
viewport_top = $window.scrollTop(),
viewport_height = $window.height(),
viewport_bottom = viewport_top + viewport_height,
$elem = $(this),
top = $elem.offset().top,
height = $elem.height(),
bottom = top + height;
return (bottom - viewport_top) / height * 100;
}
But it doesn't seem to be working. Can anyone help me out in achieveing this I seem to be spinning gears.
What you want to get is the amount of pixels that the element extends past the top and bottom of the viewport. Then you can just subtract it from the total height and divide by that height to get the percentage onscreen.
var px_below = Math.max(bottom - viewport_bottom, 0);
var px_above = Math.max(viewport_top - top, 0);
var percent = (height - px_below - px_above) / height;
return percent;
One thing to note is that jQuery's height method won't include padding. You probably want to use .outerHeight for that.
Your $elem = $(this)assignment seems wrong, here function scoping means this refers to the function you're in (ala ~ the function getPercentOnScreen), try referencing by $elem = $('#yourElementId')instead.
if you only want to calculate percent of element then just do this
function getPercentOnScreen(elem) {
$docHeight = $(document).height();
$elemHeight = $(elem).height();
return ($elemHeight/$docHeight)* 100;
}

getting the X and Y coordinates for a div element

I've been trying to make a javascript to get a X and Y coordinates of a div element. After some trying around I have come up with some numbers but I'm not sure how to validate the exact location of them(the script returns the X as 168 and Y as 258) I'm running the script with a screen resolution of 1280 x 800. This is the script I use to get this result:
function get_x(div) {
var getY;
var element = document.getElementById("" + div).offsetHeight;
var get_center_screen = screen.width / 2;
document.getElementById("span_x").innerHTML = element;
return getX;
}
function get_y(div) {
var getY;
var element = document.getElementById("" + div).offsetWidth;
var get_center_screen = screen.height / 2;
document.getElementById("span_y").innerHTML = element;
return getY;
}​
Now the question is. Would it be reasonable to assume that these are accurate coordinates returned by the function or is there an easy to to just spawn a little something on that location to see what exactly it is?
And finally how would I go about making this div element move? I know I should use a mousedown event handler and a while to keep moving the element but yeah any tips/hints are greatly appreciated my biggest concern is to how to get that while loop running.
By far, the easiest way to get the absolute screen position of an element is getBoundingClientRect.
var element = document.getElementById('some-id');
var position = element.getBoundingClientRect();
var x = position.left;
var y = position.top;
// Et voilà!
Keep in mind, though, that the coordinates don’t include the document scroll offset.
Here a simple way to get various information regarding the position of a html element:
var my_div = document.getElementById('my_div_id');
var box = { left: 0, top: 0 };
try {
box = my_div.getBoundingClientRect();
}
catch(e)
{}
var doc = document,
docElem = doc.documentElement,
body = document.body,
win = window,
clientTop = docElem.clientTop || body.clientTop || 0,
clientLeft = docElem.clientLeft || body.clientLeft || 0,
scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
top = box.top + scrollTop - clientTop,
left = box.left + scrollLeft - clientLeft;
You need to find the position using the parent's position too. There's a very good tutorial here: http://www.quirksmode.org/js/findpos.html
I think you could use jQuery .offset() http://api.jquery.com/offset/
Given the element...
<div id="abc" style="position:absolute; top:350px; left:190px;">Some text</div>
If the element is in the main document you can get the DIV's coordinates with...
var X=window.getComputedStyle(abc,null).getPropertyValue('left');
var Y=window.getComputedStyle(abc,null).getPropertyValue('top');
If the element is in an iframe you can get the DIV's coordinates with...
var X=FrameID.contentWindow.getComputedStyle(abc,null).getPropertyValue('left');
var Y=FrameID.contentWindow.getComputedStyle(abc,null).getPropertyValue('top');
NB: The returned values should be in the format "190px" and "350px".

Categories