One way to do that is to create a css rule of every position you want to use.
Assign an initial position to each of those elements (make sure each element has a different position class)
When shuffling you collect the applied positions, remove them from the elements, shuffle the array of positions and reapply them.
The shuffleArray
array function is taken form this answer 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')
// collect the positions the elements have right now and remove the current one
let positions = Array.from(items).map( item => {
// iterat over item.classLis and search for the class starting with `position-`
let positionClass = Array.from(item.classList).find(item => item.match(/^position-/))
// remove the found class
item.classList.remove(positionClass)
//return it to let the `.map` create the new array containing that class
return positionClass
})
// shuffel 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 don't want to use classes you could use the data attribute, the advantage of that would be that you give it a bit more semantic meaning, if makes it easier to retrieve the used position if you need to:
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')
// collect the positions the elements have right now and remove the current one
let positions = Array.from(items).map( item => {
return item.dataset.position;
})
// shuffel 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>