SOURCE

console 命令行工具 X clear

                    
>
console
function createCircularItems(circleContainerSelector, numItems, numLayers, centerX, centerY, initialRadius, layerSpacing) {
    const circleContainer = document.querySelector(circleContainerSelector);
    if (!circleContainer) {
        console.error(`Container ${circleContainerSelector} not found.`);
        return;
    }

    let items = [];
    let observer;
    let itemIndex = 0;

    for (let layer = 0; layer < numLayers; layer++) {
        const layerRadius = initialRadius + layer * layerSpacing;

        // 计算每层的元素数量
        const itemsPerLayer = Math.ceil(numItems * (layer + 1) / ((numLayers + 1) * numLayers / 2));

        for (let i = 0; i < itemsPerLayer; i++) {
            if (itemIndex >= numItems) break;

            const angle = (i / itemsPerLayer) * 2 * Math.PI;
            const x = centerX + layerRadius * Math.cos(angle);
            const y = centerY + layerRadius * Math.sin(angle);
            const item = document.createElement('div');

            item.classList.add('circle-item');
            item.style.left = `${x}px`;
            item.style.top = `${y}px`;
            // item.textContent = `Layer ${layer + 1}, Item ${i + 1}`;
            circleContainer.appendChild(item);

            items.push(item);
            itemIndex++;

            // 将最后一个元素连接到第一个元素,形成闭环
            if (i === itemsPerLayer - 1 && layer === numLayers - 1) {
                const finalAngle = 0; // 最后一个元素连接到第一个元素的角度
                const finalX = centerX + layerRadius * Math.cos(finalAngle);
                const finalY = centerY + layerRadius * Math.sin(finalAngle);

                const finalItem = document.createElement('div');
                finalItem.classList.add('circle-item');
                finalItem.style.left = `${finalX}px`;
                finalItem.style.top = `${finalY}px`;
                // finalItem.textContent = `Layer ${layer + 1}, Item ${i + 2}`;
                circleContainer.appendChild(finalItem);

                items.push(finalItem);
                itemIndex++;
            }
        }
    }

    observer = new IntersectionObserver((entries, observer) => {
        const allOutOfView = entries.every(entry => entry.intersectionRatio === 0);

        if (allOutOfView) {
            items.forEach(item => {
                item.style.transition = 'opacity 0.5s ease-in-out';
                item.style.opacity = '0';
            });
        } else {
            items.forEach((item, index) => {
                setTimeout(() => {
                    item.style.transition = 'opacity 0.5s ease-in-out';
                    item.style.opacity = '1';
                }, index * 30); // 每个元素延迟 20ms 显示
            });
        }
    }, { threshold: 0 });

    observer.observe(circleContainer);
}

// 示例调用,创建三层的圆形布局,共55个元素
createCircularItems('.circle-container', 36, 3, 10, 10, 30, 30);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Circular Loading Animation</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="circle-container">
    <!-- 这里是动态生成的 DOM 元素 -->
  </div>
  <!-- <div class="circle-container-2"> -->
    <!-- 这里是动态生成的 DOM 元素 -->
  <!-- </div> -->

  <script src="script.js"></script>
</body>
</html>
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300vh;
  margin: 0;
  background-color: #f0f0f0;
}

.circle-container {
  position: relative;
  width: 200px;
  height: 200px;
  /* background: pink; */

}

/* .circle-container-2 {
  position: relative;
  width: 200px;
  height: 200px;
  margin-top: 800px;

} */

.circle-item {
  position: absolute;
  left: 50%;;
  top: 50%;
  transform: translate(-50%,-50%);
  width: 24px;
  height: 24px;
  background-color: #3498db;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 14px;
  color: white;
  opacity: 0; /* 初始状态为隐藏 */
  transition: opacity 0.5s ease; /* 过渡效果 */
}