What is the best way to resize several divs while ensuring they remain within a specific container?

In the process of creating a grid UI, I want users to be able to click on cells and scale them.

Intended Outcome:

  • Cells should be prevented from scaling out of the container and being cropped.
  • Cells can overlap with one another when scaled.
  • Only one cell needs to be scaled at a time, although this is not a top priority.

Undesired Behavior: (parts of cell O disappear) Desired Behavior: https://i.sstatic.net/4Ipgy.png

My Strategy:

My plan is to use the transform: scale() translate() properties simultaneously to achieve the desired effect. This can be observed with cell N (translateY(22px)).

Challenges:

This method does not scale effectively when there are 9 cells, let alone the 90 cells in my real use case.

The container must have an overflow: hidden setting. Scrolling is not an acceptable solution.

My Inquiry:

It seems like my current approach to solving this problem is quite basic, and there may be a more efficient way to accomplish this programmatically.

Is there a more effective method to construct such a UI? (I am open to utilizing plugins or trying alternative methods).

If not, what is a recommended way to script this using jQuery?

$(function() {
$(".cell").click(function() {
    $(this).toggleClass("zoom-in");
  });
});
.grid {
  width: 300px;
  height: 300px;
  background: gray;
  overflow: hidden;
}

.cell {
  background: tomato;
  width: 30%;
  height: 30%;
  margin: 5px;
  float: left;
  text-align: center;
  z-index: 999;
  transition: all 0.2s ease-in-out;
}

.zoom-in {
  transform: scale(2);
  transition: all 0.2s ease-in-out; 
}

#nord {
  background-color: white;
}
#nord.zoom-in {
  transform: scale(2) translateY(22px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div> Click white and red cells to scale. Click again to revert.</div>
<div class="grid">
  <div class="cell">NW</div>
  <div id="nord" class="cell">N</div>
  <div class="cell">NO</div>
  <div class="cell">W</div>
  <div class="cell">C</div>
  <div class="cell">O</div>
  <div class="cell">SW</div>
  <div class="cell">S</div>
  <div class="cell">SO</div>
</div>

Answer №1

For a project I was working on, I developed a similar concept to serve as a prototype. I believe it could provide some guidance in the right direction. Feel free to explore the demonstration I put together: https://codepen.io/RTakes/pen/aWejOy

My approach to centering and scaling involved calculating the target position to animate to, starting from the current position of the element.

function determineCenterPosition(item, scalingFactor = 0) {
  const centerScreen = {
    x: window.innerWidth / 2,
    y: window.innerHeight / 2
  };

  const itemCenter = {
    x: (item.offsetWidth / 2) + item.offsetLeft,
    y: (item.offsetHeight / 2) + item.offsetTop
  };

  return {
    x: (itemCenter.x - centerScreen.x) * -1,
    y: (itemCenter.y - centerScreen.y) * -1
  }
}

Answer №2

I implemented a function to check if a cell is close to any border of the grid. If it is, the function applies a style to the cell that causes it to move in the opposite direction when zoomed.

While this solution works, it is quite basic and there is definitely room for optimization.

$(function() {
$(".cell").click(function() {
    $(this).toggleClass("zoom-in");
  });
});

document.addEventListener('DOMContentLoaded', setEvent, false);

function setEvent () {
    var elements = document.getElementsByClassName('cell');
    var grid = elements[0].parentElement;

    var gridWidth = grid.clientWidth;
    var gridHeight = grid.clientHeight;
    var maxGrid = {
        right: gridWidth,
        bottom: gridHeight
    }

    for (var n = 0; n < elements.length; n++) {
        evaluate (elements[n], maxGrid);
    }
}

function evaluate (element, maxGrid) {

    var transOrigin = "";

    var left = element.offsetLeft;
    if (left < element.clientWidth) {
        transOrigin += 'left ';
    }
    if (left + element.clientWidth > maxGrid.right - element.clientWidth) {
        transOrigin += 'right ';
    }

    var top = element.offsetTop;
    if (top < element.clientHeight) {
        transOrigin += 'top';
    }
    if (top + element.clientHeight > maxGrid.bottom - element.clientHeight) {
        transOrigin += 'bottom';
    }

    element.style.transformOrigin = transOrigin;
}
.grid {
  width: 300px;
  height: 300px;
  background: gray;
  overflow: hidden;
  position: relative; /* important to have this */
}

.cell {
  background: tomato;
  width: 30%;
  height: 30%;
  margin: 5px;
  float: left;
  text-align: center;
  z-index: 999;
  transition: all 0.2s ease-in-out;
}

.zoom-in {
  transform: scale(2);
  transition: all 0.2s ease-in-out; 
}

#nord {
  background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div> Click white and red cells to scale. Click again to revert.</div>
<div class="grid">
  <div class="cell">NW</div>
  <div id="nord" class="cell">N</div>
  <div class="cell">NO</div>
  <div class="cell">W</div>
  <div class="cell">C</div>
  <div class="cell">O</div>
  <div class="cell">SW</div>
  <div class="cell">S</div>
  <div class="cell">SO</div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Working with jqgrid: Using a custom formatter to retrieve the column index

How to retrieve column index using custom formatter? In the "Tax" column, I am attempting to use a custom formatter. I need to obtain the column index value and the row index value. While I can fetch the irow parameter with options.rowid, there seems to b ...

Display Jquery UI Autocomplete conditionally with a specific key press

I have a textbox with autocomplete feature, and I want the results to show only when the dot key "." is pressed. Here's what I've tried: $("#tags").on("keypress", function () { var keys = []; keys.unshift(e.which); if (String.fr ...

Creating a text input with a CSS gradient

Can the text color of an input be set as a gradient? I came across this method for regular static text but it doesn't seem to work for inputs: h1 { font-size: 72px; background: -webkit-linear-gradient(to right, rgb(66, 251, 227), rgb(43, 43, 2 ...

Rails controller did not receive the Ajax call

I have noticed that when I make an Ajax call using jQuery, the data is always transmitted (status 200), but there are times when it's not properly received by the Rails controller. The data is sent correctly, but most of the time the controller respon ...

Is there a way to determine the total number of colors present in an image?

<?php $img=imagecreatefrompng('dense.png'); list($width, $height)=getimagesize('dense.png'); $t=0; for( $i=0 ; $i<$height ; $i++ ) { for( $j=0 ; $j<$width ; $j++ ) { $pix = imagecolorat($img, $i, $j); ...

Is the input box failing to show up on your screen?

I recently tackled the task of creating a commenting feature for RSS articles Throughout my journey with PHP coding, I encountered an issue where the input box for comments was not displaying. https://i.stack.imgur.com/gJIlu.png Check out the snippet fr ...

Unable to use document.write when extracting code from the internet

I am currently developing a game using emulatorjs and ruffle. The goal is to have it all contained in a single downloadable file that can be run locally. I attempted to create another file for auto-updating purposes, but encountered issues with some of the ...

What is the best way to extract content between <span> and the following <p> tag?

I am currently working on scraping information from a webpage using Selenium. I am looking to extract the id value (text) from the <span id='text'> tag, as well as extract the <p> element within the same div. This is what my attempt ...

Controlling a complex IF statement with jQuery

Currently, I have an if statement with over 100 different conditions. Right now, I am using a structure similar to this... $('select').on("change",function(){ if( $(this).val() === 'tennis' ) { $('.sport').val( ...

Anchor tag in AngularJS not responding to ng-disabled directive

I have been successfully using ng-disabled for input and buttons, but I have run into an issue with anchor tags. How can I make it work for anchor tags as well? HTML code <a ng-disabled="addInviteesDisabled()">Add</a> JS code $scope.addIn ...

How can you Use CSS to Float Elements Left and Right while adjusting their Width Dynam

Is it possible to have two columns side by side with dynamic text using only CSS? I'm trying to make the left main text "break" into a new line when it reaches the right category, which is also dynamic. Do I need to use JavaScript for this? https://i ...

JQuery Mobile's Panel widget is the culprit behind the demise of the

I'm having some trouble adding a panel to my jQuery mobile page. Every time I try to input the code, all I see is a white screen with the loading widget, and nothing else happens. I have JQuery 2.0.0 hosted by Google, JQuery Mobile JS 1.3.1 hosted by ...

How to position the play button in the center using Material UI and Flexbox

Seeking advice on achieving a centered play button with borders in this layout. Struggling with flexbox to position the play button within the code provided. function Tasks(props) { const { classes } = props; return ( <div className={classe ...

Numerous categories housed within various div containers

I am working with an HTML code that contains 6 different div elements: <div class="hisclass1 hisclass2 myclass hisclass3"> <div class="herclass1 herclass2"> <!-- 2nd div --> </div> </di ...

Leveraging the power of Google Closure Templates alongside the versatility of

We are embarking on developing an application using JavaScript and HTML5 that will utilize a rest API to access server resources, leveraging the power and convenience of jQuery which our development team is already proficient in. Our goal is to make this a ...

Understanding the concept of for loops in JavaScript and incorporating them in CSS styling

Hello there! I initially used this code to draw 12 lines, but now I am looking to incorporate a for loop and implement it in CSS. Can someone please guide me on how to proceed? <!DOCTYPE html> <html> <head> <style> #straigh ...

jQuery removes HTML tags from XML documents

I currently have a setup where a page is functioning as an AJAX loader with the help of jQuery. It is designed to retrieve XML documents, like the one shown below, and then place the values of title, authPhrase, and content into the appropriate div element ...

Troubleshooting HTML navigation bar white space problem

I am encountering a white space issue with my HTML nav bar for the first time. I have managed to fix the space on the sides (left and right), but there is still some space at the top of the nav bar. Can someone please assist me in resolving this issue? To ...

Enhancing your JQuery Select2 plugin by incorporating a Checkbox feature

I am currently utilizing the jQuery select2 plugin to enable multiple selections. My goal is to incorporate a checkbox for each selectable option. Depending on whether the checkbox is checked or unchecked, the dropdown option should be selected accordingl ...

Is it possible to add a border to both the tbody and td

I currently have a table that is organized with tbody elements to group rows together. In order to create a grid-like structure, I applied borders to each individual td element within the tbody. However, I also desire to show that the tbodies themselves ar ...