JavaScript Math to dynamically shift elements within a div for fit

I’m working on a card game in JS. The player’s cards are dynamically displayed as elements inside a div of a set width. As cards are added to the player’s hand, I’m using `right: %` and `z-index` to shift all cards left and have them overlap each other, thereby making room to display more cards within the div (which is set to `white-space: nowrap` so content inside it won't break to a new line).

I’m using JS to calculate and set the percentage for the cards to shift left, based on each card’s original position and the total number of cards that need to be displayed.

The general plan is working, but I’m having trouble figuring out how to calculate a percentage that will work for any number of cards. Ideally, I'd like the cards to shift left just enough so that no matter how many there are they never extend outside the div but always fill it completely.

I thought the following would work:

``````function displayHand(cards) {
for(var i = 0; i < cards.length; i++) {
var cardDiv = document.createElement("div");
document.getElementById(“playerHand”).appendChild(cardDiv);
if(cards.length > 7) {
cardDiv.setAttribute("style", "z-index: " + i + "; right: "
+ (i * cards.length) * (0.04815 * cards.length) + "%");
}
}
``````

However, I seem to be getting this formula wrong: `(i * cards.length) * (0.04815 * cards.length)`. (Note that the 0.04815 number came from tinkering and trying to get the percentage right.)

By increasing the 0.04815 number I can make a small number of cards (i.e. 8-12) fit well but a larger number will be shifted much too close together, filling only a small portion of the div. If I decrease the number, 12 cards will overflow the div but a larger number will fit well inside it.

The problem comes from the fact that you don't need the first card to move. Your `cards.length` factor is too high.

Instead, you need only consider `cards.length-1`.

For instance, let's say I can fit in two cards exactly. To add a third card, I would need to move the cards left for a total of 1 card width by the time two cards (after the first) have been placed. That is, at 50% and 100%. Adding a fourth card would result in the cards being shifted at 1/3, 2/3 and 3/3. And so on.

So it should simply be a case of moving it by `i * (cards.length-1) * (card width here)`

Webpack: ES6 syntax gives Module build failed: SyntaxError: Unexpected token

I'm trying to use an example of fixed-data-table, and bundle it with webpack. I'm using babel-loader and my code otherwise bundles without issues. Running webpack points to an error which to my ...

I'm trying to use an example of fixed-data-table, and bundle it with webpack. I'm using babel-loader and my code otherwise bundles without issues. Running webpack points to an error which to my ...

Replacing HTML with JavaScript changed style, images no longer in-line horizontally

I'm new to coding and I replaced some repetitive HTML with JavaScript and now the images, which used to display 4 across, are no longer displaying horizontally. They now display on the left only. I've ...

I'm new to coding and I replaced some repetitive HTML with JavaScript and now the images, which used to display 4 across, are no longer displaying horizontally. They now display on the left only. I've ...

1. replacing html with jquery
2. replacing html with javascript
3. replacing html text with javascript
4. replacing html tables with divs

Three.js finding vertices of buffergeometry after .fromGeometry();

How do I find vertices positions of a mesh after I used .fromGeometry(); code? I created a buffergeometry from a geomtery that I used for a mesh. Here is an example. var geom = new THREE.BoxGeometry(...

How do I find vertices positions of a mesh after I used .fromGeometry(); code? I created a buffergeometry from a geomtery that I used for a mesh. Here is an example. var geom = new THREE.BoxGeometry(...

JS displays HTML instead of the input value

Here is my input <input type="text" class="ChampionInput" list="champions" name="champion[]"`placeholder="Champion" required> And here is my js document.forms["first_form_champions"].oninput ...

Here is my input <input type="text" class="ChampionInput" list="champions" name="champion[]"`placeholder="Champion" required> And here is my js document.forms["first_form_champions"].oninput ...

1. firefox displays html code instead of page
1