To achieve this, one effective method is to establish a CSS rule for each specific position you intend to utilize.
Assign an initial position to all elements (ensure that each element possesses a distinct position class).
During the shuffling process, capture the positions applied, remove them from the elements, shuffle the array of positions, and then reapply them.
The shuffleArray
function originates from this response to "How to randomize (shuffle) a JavaScript array?"
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
function shuffelPositions() {
let items = document.querySelectorAll('.item')
// Capture the current element positions and eliminate the existing ones
let positions = Array.from(items).map( item => {
// Iterate over item.classList and search for classes starting with `position-`
let positionClass = Array.from(item.classList).find(item => item.match(/^position-/))
// Remove the located class
item.classList.remove(positionClass)
// Return it to allow the `.map` to create a new array containing that class
return positionClass
})
// Shuffle those positions
shuffleArray(positions)
// Apply the shuffled positions
for (let i = 0; i < items.length; i++) {
items[i].classList.add(positions[i])
}
}
document.getElementById('shuffle').addEventListener('click', shuffelPositions)
.items--cloud {
position: relative;
height: 400px;
width: 500px;
background: #333;
}
[data-item] {
position: absolute;
transform: translate3d(var(--x), var(--y), 0);
}
.position-1 {
right: 0%; top: 40%;
}
.position-2 {
right: 53%;top: 28%;
}
.position-3 {
right: 39%;top: 4%;
}
.position-4 {
right: 79%;top: 26%;
}
<div class="items--cloud">
<div data-item="item-1" class="item item-1 position-1">
<img src="https://via.placeholder.com/90x90.?text=item1" alt="">
</div>
<div data-item="item-2" class="item item-2 position-2">
<img src="https://via.placeholder.com/90x90?text=item2" alt="">
</div>
<div data-item="item-3" class="item item-3 position-3">
<img src="https://via.placeholder.com/90x90?text=item3" alt="">
</div>
<div data-item="item-4" class="item item-4 position-4">
<img src="https://via.placeholder.com/90x90?text=item4" alt="">
</div>
</div>
<button id="shuffle">shuffle positions</button>
If you prefer not to use classes, utilizing the data attribute could be another approach. This has the benefit of providing additional semantic meaning, making it easier to retrieve the utilized position if necessary:
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
function shuffelPositions() {
let items = document.querySelectorAll('.item')
// Capture the current element positions and remove the existing ones
let positions = Array.from(items).map( item => {
return item.dataset.position;
})
// Shuffle those positions
shuffleArray(positions)
// Apply the shuffled positions
for (let i = 0; i < items.length; i++) {
items[i].dataset.position = positions[i]
}
}
document.getElementById('shuffle').addEventListener('click', shuffelPositions)
.items--cloud {
position: relative;
height: 400px;
width: 500px;
background: #333;
}
[data-item] {
position: absolute;
transform: translate3d(var(--x), var(--y), 0);
}
[data-position="1"] {
right: 0%; top: 40%;
}
[data-position="2"]{
right: 53%;top: 28%;
}
[data-position="3"]{
right: 39%;top: 4%;
}
[data-position="4"] {
right: 79%;top: 26%;
}
<div class="items--cloud">
<div data-item="item-1" class="item item-1" data-position="1">
<img src="https://via.placeholder.com/90x90.?text=item1" alt="">
</div>
<div data-item="item-2" class="item item-2" data-position="2">
<img src="https://via.placeholder.com/90x90?text=item2" alt="">
</div>
<div data-item="item-3" class="item item-3" data-position="3">
<img src="https://via.placeholder.com/90x90?text=item3" alt="">
</div>
<div data-item="item-4" class="item item-4" data-position="4">
<img src="https://via.placeholder.com/90x90?text=item4" alt="">
</div>
</div>
<button id="shuffle">shuffle positions</button>