You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Anime.js六边形网格stagger偏移问题:仅1080px正常,其他分辨率异常

问题:六边形网格交错淡出效果在不同分辨率下异常的修复

我是前端开发新手,正在修改教程实现点击时淡出的交错六边形网格效果,使用anime.js完成。

该效果在1080px宽度下可正常运行:
正常的六边形交错效果

但切换至1600px等其他分辨率时:
左下角六边形效果异常

左下角的六边形会与整体效果脱节,影响体验。不确定anime.js的问题出在哪,请问如何修复该问题,使效果在所有分辨率下正常运行?


运行代码

HTML

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Untitled Document</title>
        <link rel="stylesheet" href="./homepage.css">
    </head>

    <body>

        <!-- hexagonal grid -->
        <div class="containercontainer">
            <div class="hexagoncontainer">
                  <div id="hexagons"></div>
            </div>
        </div>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
        <script src="./homepage.js"></script>


    </body>
</html>

CSS

/* CSS Document */

@keyframes background-pan {
  from {
    background-position: 0% center;
  }

  to {
    background-position: -200% center;
  }
}

body {
    width:100%;
    overflow-x: hidden;
}

.containercontainer {
    animation: background-pan 10s linear infinite;
    background: linear-gradient(
        to right,
        rgb(98,0,234),
        rgb(236,64,122),
        rgb(98,0,234)
    );

    background-size: 200%;
    height: 100vh;
    overflow: hidden;
    margin-left: -75px;
    margin-right: -200px;
    margin-top: -50px;
    margin-bottom: -10px;
}

.hexagoncontainer {
    --s: 100px;  /* size of a hexagon */
    --m: 1px;   /* space between each heaxgon */
    --r: calc(var(--s)*3*1.1547/2 + 4*var(--m));
    display:flex;
}

#hexagons div {
  width: var(--s);
  height: calc(var(--s)*1.1547); 
  margin: var(--m);
  display: inline-block;
  clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
  margin-bottom: calc(var(--m) - var(--s)*0.32); 
}

#hexagons::before {
  content: "";
  width: calc(var(--s)/2 + var(--m));
  float: left;
  height: 100%;
  shape-outside: repeating-linear-gradient(     
                  transparent 0 calc(var(--r) - 3px),      
                  #fff        0 var(--r));
}

.hexagon {
    background-color: rgb(20, 20, 20);
}

JavaScript

const wrapper = document.getElementById("hexagons");

let columns = 0, rows = 0, toggled = false;

const hexagonOnClick = index => {
    toggled = !toggled;

    anime({
        targets: ".hexagon",
        opacity: toggled ? 0 : 1,
        delay: anime.stagger(50, {
            grid: [columns, rows],
            from: index
        })
    });
}

const createTile = index => {
    const tile = document.createElement("div");

    tile.classList.add("hexagon");

    tile.onclick = e => hexagonOnClick(index);

    tile.style.opacity = toggled ? 0 : 1;

    return tile;
}

const createTiles = quantity => {
    Array.from(Array(quantity)).map((tile, index) => {
        wrapper.appendChild(createTile(index));
    });
}

const createGrid = () => {
    wrapper.innerHTML = "";

    const size = document.body.clientWidth > 800 ? 100 : 50;

    columns = Math.floor(document.body.clientWidth / size) + 2;
    rows = Math.floor(document.body.clientHeight / size) + 2;

    wrapper.style.setProperty("--columns", columns)
    wrapper.style.setProperty("--rows", rows);
    wrapper.style.setProperty("--hexagonSize", size);

    createTiles(columns * rows);
}

createGrid();

window.onresize = () => createGrid();

问题根源

六边形布局通过CSS shape-outside实现了交错排列,但anime.js的stagger效果基于规整行列网格和元素的一维索引计算延迟,两者布局逻辑不匹配:

  • CSS中偶数行(视觉第一行)会偏移半个六边形宽度,导致元素的一维索引对应的网格位置和实际视觉位置不符
  • 左下角第一个元素(索引0)在视觉上属于半偏移位置,而anime.js会将其视为规整网格的[0,0]点,导致扩散逻辑错位

修复方案

修改点击事件中的stagger计算逻辑,适配六边形的交错布局:

修改后的JavaScript代码

const wrapper = document.getElementById("hexagons");

let columns = 0, rows = 0, toggled = false;

const hexagonOnClick = index => {
    toggled = !toggled;
    // 计算当前元素的行和列(基于一维索引)
    const row = Math.floor(index / columns);
    let col = index % columns;
    
    // 适配交错布局:偶数行的列偏移0.5,匹配视觉位置
    const adjustedCol = row % 2 === 0 ? col + 0.5 : col;

    anime({
        targets: ".hexagon",
        opacity: toggled ? 0 : 1,
        delay: anime.stagger(50, {
            // 列数加0.5,适配交错布局的偏移量
            grid: [columns + 0.5, rows],
            // 使用调整后的视觉位置作为扩散起点
            from: [adjustedCol, row]
        })
    });
}

const createTile = index => {
    const tile = document.createElement("div");

    tile.classList.add("hexagon");

    tile.onclick = e => hexagonOnClick(index);

    tile.style.opacity = toggled ? 0 : 1;

    return tile;
}

const createTiles = quantity => {
    Array.from(Array(quantity)).map((tile, index) => {
        wrapper.appendChild(createTile(index));
    });
}

const createGrid = () => {
    wrapper.innerHTML = "";

    const size = document.body.clientWidth > 800 ? 100 : 50;

    columns = Math.floor(document.body.clientWidth / size) + 2;
    rows = Math.floor(document.body.clientHeight / size) + 2;

    wrapper.style.setProperty("--columns", columns)
    wrapper.style.setProperty("--rows", rows);
    wrapper.style.setProperty("--hexagonSize", size);

    createTiles(columns * rows);
}

createGrid();

window.onresize = () => createGrid();

关键修改点

  1. 调整列位置:根据元素所在行的奇偶性,给偶数行的列加0.5偏移,匹配CSS布局带来的半宽度位移
  2. 适配网格参数:将stagger的grid列数设置为columns + 0.5,让anime.js的网格计算逻辑适配交错布局
  3. 修正扩散起点:使用调整后的[adjustedCol, row]作为动画扩散的起点,确保动画效果和视觉布局完全对齐

修改后,无论在任何分辨率下,六边形的交错淡出/淡入效果都会从点击位置正确扩散,左下角元素不会再出现脱节问题。


内容的提问来源于stack exchange,提问作者Minater 247

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:30:44