Reputation: 69
I'm trying to create a 3D layers effect of multiple overlapping divs that appear to get more distant with each div. Something like the image below.
To achieve the 3D effect; I'm applying right and top spacing to each div with inline css styles. The spacing would vary depending on the number of divs there are.
I need to generate the right and top position numbers for each div to achieve this effect, which will vary depending on the number of divs.
I have a simple effect working by dividing the max number by the number of divs. However this makes the gap between each div equal and so the 3D effect isn't as convincing.
Each div is added to the DOM using a for loop. Something similar to the following
var divsToGenerate = 14;
var divsArr;
var css = {top: 0, right: 335}
for( var i = 0; i < divsToGenerate; i++ ) {
css = {top: 35, right: 300}
divsArr += '<div style="top:'+ css.top +'; right:'+ css.right +'"></div>';
}
I'm having trouble generating the numbers between 335 and 0 that would gradually decrease the gap between each passing div. Giving it a layered 3D effect.
Upvotes: 0
Views: 98
Reputation: 322
Using similar arithmetic as described by @johannes I adjusted your script to do something closer to what you desire. Only thing I changed was to use a negative exponent so that we can start at the top and decrease our increments towards the later iterations.
Here's the fiddle in case the embedded snippet doesn't work.
// parameters
var divsToGenerate = 10;
var divsArr = "";
var css = {top: 100, right: 200} // starting position of first div
var max = 70; // max spacing
// use negative exponential function
for( var i = 0; i < divsToGenerate; i++ ) {
let x = i / divsToGenerate-1;
x = 1 - x;
x = Math.pow(x, -2); // negative exponent
x = x * max; // scale to range
divsArr += `<div style="top:${css.top - x}px; right:${css.right + x}px;"></div>`;
}
document.body.innerHTML = divsArr;
div {
border:1px solid black;
width:100px;
height:150px;
position:absolute;
background:white;
}
Upvotes: 1
Reputation: 381
You can generate a sequence like this:
[...Array(14).keys()] // generate array from 0 to 13
.map(x => x / 13) // convert to a value between 0 and 1
.map(x => 1 - x) // go from high to low
.map(x => Math.pow(x, 2)) // square to gradually decrease the difference
.map(x => 335 * x) // convert to a value between 0 and 335
.map(x => x.toFixed(0)) // discard decimal places
You can change the exponent Math.pow(x, 2)
to alter how quickly the transition takes place, or use Math.exp
instead.
Upvotes: 2