最近,公司要做一個類似挖礦的項目,大概其是當用戶登錄進入首頁后,如果用戶有已經生成的原力值,則在其點擊原力值后可以類似螞蟻森林那樣收集原力值,當用戶將所有的原力值收集完畢后開始提醒用戶新的原力值正在生成中,待新的原力值生成后,用戶可以繼續以上的操作收集原力值。如下圖:
以上是一種邏輯,還有一種是當用戶前一天有剩余的原力值沒有收集時,在第二天收集完當天的已生成的原力值后,前一天的原力值還可以出現在頁面當中繼續供用戶收集(具體的情況,看你公司的實際業務需求,比如可以設置三天內的原力值都能收集,也可以設置兩天內的原力值可供收集等)。
本文不考慮后端業務邏輯的實現,只分享前端多個原力值在頁面中的隨機不重疊分布的實現方法,在此之前,我本來想參考網易星球的實現方法(算法),但人家的是APP的項目,根本看不到具體是如何實現的,后來又參考了其他的實現方法,發現其雖然也是有一定的隨機性,但元素距離左邊的距離其實是固定死的,只有距離頂部的距離是隨機的,而且元素基本上就是只分兩行隨機分布。如下圖:
圓圈1那個圓其實永遠都在第一行的第一個位置,其唯一變化的就是它距離頂部的距離,其他的圓圈也是類似,這樣給人的效果就不理想。再后來,也參考過其他的一些寫法,效果都不好。那么,以下就是本篇博客所要實現的代碼,妥妥滴的滿足了開發的需要:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no,viewport-fit=cover">
<title>js多個元素隨機且不重疊分布在頁面中</title>
<script>
//計算根節點HTML的字體大小
function resizeRoot(width) {
var deviceWidth = document.documentElement.clientWidth,
num = width,
num1 = num / 100;
if (deviceWidth > num) {
deviceWidth = num;
}
document.documentElement.style.fontSize = deviceWidth / num1 + "px";
}
//根節點HTML的字體大小初始化
resizeRoot(750);
window.onresize = function () {
resizeRoot(750);
};
</script>
<style>
*{margin:0;padding:0;}
.demo{height:5rem;position:relative;}
img{width:.8rem;height:.8rem;position:absolute;border-radius:50%;}
</style>
</head>
<body>
<div class="demo"></div>
<script>
createBubble(10); //初始化氣泡
function createBubble(num){
var iconWidth = 60; //值越大,元素左右間隔越大
var iconHeight = 60; //值越大,元素上下間隔越大
var targetHeight = document.querySelector(".demo").offsetHeight;
var targetWidth = document.querySelector(".demo").offsetWidth;
var _tmpArray = [];
var html = '';
//當放置的元素的寬高大於瀏覽器窗口的寬高時,直接返回
if(targetWidth < iconWidth || targetHeight < iconHeight){
return false;
}
var xNum = parseInt(targetWidth / iconWidth, 10); //用瀏覽器的寬度除以一個元素的寬度可算出瀏覽器窗口內一行可以放置元素的個數
var yNum = parseInt(targetHeight / iconHeight, 10); //用瀏覽器的高度除以一個元素的高度可算出瀏覽器窗口內一列可以放置元素的個數
var allNum = xNum * yNum; //瀏覽器窗口內總共可以放置元素的個數
//當需要放置的元素的個數超過瀏覽器窗口內總共可以放置的元素的個數時,則返回
if(num >= allNum){
return false;
}
for(var i = 0; i < allNum; i++){
_tmpArray.push(i);
}
var xStart = 0, yStart = 0;
while(num){
var pointer = Math.floor(Math.random() * allNum); //向下取整取出0到allnum之間的任意一個整數
//如果數組_tmpArray中不存在第pointer值,則繼續
if(!_tmpArray[pointer]){
continue;
}
delete _tmpArray[pointer]; //刪除數組_tmpArray中第pointer個值
yStart = parseInt(pointer / xNum, 10) * iconWidth;
xStart = (pointer % xNum) * iconHeight;
html += "<img src='http://tp1.sinaimg.cn/1642634100/50/5613120647/0' style='top:" + yStart + "px;left:" + xStart + "px'/>";
num--;
}
document.querySelector(".demo").innerHTML = html;
}
</script>
</body>
</html>