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();
关键修改点
- 调整列位置:根据元素所在行的奇偶性,给偶数行的列加0.5偏移,匹配CSS布局带来的半宽度位移
- 适配网格参数:将
stagger的grid列数设置为columns + 0.5,让anime.js的网格计算逻辑适配交错布局 - 修正扩散起点:使用调整后的
[adjustedCol, row]作为动画扩散的起点,确保动画效果和视觉布局完全对齐
修改后,无论在任何分辨率下,六边形的交错淡出/淡入效果都会从点击位置正确扩散,左下角元素不会再出现脱节问题。
内容的提问来源于stack exchange,提问作者Minater 247
相关产品推荐
相关产品推荐

