Phaser 3:如何实现5x5网格变形以制作近大远小的步道?
实现近大远小步道网格及顶部动态添加功能
核心思路
利用CSS 3D透视特性实现网格的近大远小效果,配合JavaScript动态添加顶部网格行并更新透视参数,维持视觉一致性。
实现步骤
1. 基础HTML结构
构建透视容器、网格行容器,以及添加按钮:
<div class="perspective-container"> <div class="grid-rows"> <!-- 初始5行网格 --> <div class="grid-row"> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> </div> <div class="grid-row"> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> </div> <div class="grid-row"> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> </div> <div class="grid-row"> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> </div> <div class="grid-row"> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> <div class="grid-block"></div> </div> </div> <button id="addRowBtn">添加顶部网格行</button> </div>
2. CSS 3D透视与缩放设置
通过透视容器和自定义变量控制每行的Z轴位置与缩放比例,实现近大远小:
.perspective-container { perspective: 800px; /* 调整此值改变透视强度 */ width: fit-content; margin: 50px auto; } .grid-rows { transform-style: preserve-3d; /* 开启3D空间继承 */ } .grid-row { display: flex; gap: 8px; margin-bottom: 8px; /* 利用--row-index变量控制每行的3D变换 */ transform: translateY(-20px) translateZ(calc(var(--row-index) * -60px)) scale(calc(1 - var(--row-index) * 0.15)); transition: all 0.3s ease; } .grid-block { width: 80px; height: 80px; background-color: #e0e0e0; border: 1px solid #ccc; } /* 初始5行的--row-index赋值:最底部(最近)行索引为0,缩放最大 */ .grid-row:nth-child(1) { --row-index: 4; } .grid-row:nth-child(2) { --row-index: 3; } .grid-row:nth-child(3) { --row-index: 2; } .grid-row:nth-child(4) { --row-index: 1; } .grid-row:nth-child(5) { --row-index: 0; }
3. JavaScript动态添加逻辑
点击按钮时创建新的5列网格行,插入到顶部,并重新计算所有行的--row-index变量,维持透视效果:
const addRowBtn = document.getElementById('addRowBtn'); const gridRowsContainer = document.querySelector('.grid-rows'); addRowBtn.addEventListener('click', () => { // 创建新网格行 const newRow = document.createElement('div'); newRow.className = 'grid-row'; // 添加5个网格块 for (let i = 0; i < 5; i++) { const block = document.createElement('div'); block.className = 'grid-block'; newRow.appendChild(block); } // 插入到网格容器最顶部 gridRowsContainer.insertBefore(newRow, gridRowsContainer.firstChild); // 更新所有行的--row-index变量 const allRows = gridRowsContainer.querySelectorAll('.grid-row'); allRows.forEach((row, idx) => { // 最顶部行对应最大的--row-index值(最远) row.style.setProperty('--row-index', allRows.length - 1 - idx); }); });
关键细节说明
perspective值决定透视效果的强弱,数值越小透视越夸张,可根据需求调整。translateZ和scale的系数可配合调整,保证网格行之间的间距和缩放比例协调。- 动态添加行后必须重新计算
--row-index,否则新行无法融入现有透视层级。
内容的提问来源于stack exchange,提问作者FeelRightz
相关产品推荐
相关产品推荐

