我想制作一个像 Wii 菜单转换一样的动画,当你点击一个频道时:
如您所见,窗口放大到频道,然后频道页面打开。通道周围没有任何东西扭曲,这意味着通道组件的尺寸没有增长(我想)。
据说Wii菜单是用HTML编码的,所以应该可以吧?
我尝试使点击的图像随着背景变小而变大,但结果与原始结果相去甚远。另外,我找不到能够做到这一点的框架或库,甚至没有一个具有这样的动画的网站。如果你发现了什么,请告诉我。
我使用一些人工智能辅助进行构建。想法是在与网格中单击的单元格相同的位置上创建一个固定位置节点。使用
getBoundingClientRect
有很大帮助。当然,使用 transition
来更改坐标,即缩放。
const gridContainer = document.getElementById("gridContainer")
const closeButton = document.getElementById("closeButton")
const gridColumns = 9
const gridRows = 3
var clonedCell
var rect
function createGrid() {
for (let i = 0; i < gridColumns * gridRows; i++) {
const cell = document.createElement("div")
cell.className = "grid-cell"
cell.style.backgroundImage = `url(https://picsum.photos/300/300?random=${i})`
cell.addEventListener("click", () => zoomCell(cell))
gridContainer.appendChild(cell)
}
}
function zoomCell(cell) {
rect = cell.getBoundingClientRect()
const startTop = rect.top
const startLeft = rect.left
const startWidth = rect.width
const startHeight = rect.height
clonedCell = cell.cloneNode(true)
document.body.appendChild(clonedCell)
clonedCell.style.position = "fixed"
clonedCell.style.top = startTop + "px"
clonedCell.style.left = startLeft + "px"
clonedCell.style.width = startWidth + "px"
clonedCell.style.height = startHeight + "px"
clonedCell.style.zIndex = "10"
clonedCell.style.borderRadius = "20px"
requestAnimationFrame(function() {
gridContainer.style.opacity = 0;
clonedCell.style.transition = "all 0.5s ease"
clonedCell.style.top = "0"
clonedCell.style.left = "0"
clonedCell.style.width = "100vw"
clonedCell.style.height = "100vh"
clonedCell.addEventListener("click", resetZoom)
})
}
function resetZoom() {
if (clonedCell) {
clonedCell.style.top = rect.top + "px"
clonedCell.style.left = rect.left + "px"
clonedCell.style.width = rect.width + "px"
clonedCell.style.height = rect.height + "px"
gridContainer.style.opacity = 1;
setTimeout(() => {
clonedCell.remove()
clonedCell = null;
}, 500)
}
}
createGrid()
body,
html {
margin: 0;
padding: 0;
height: 100%;
overflow-y: hidden;
}
.grid-container {
display: grid;
grid-template-columns: repeat(9, 250px);
grid-template-rows: repeat(3, 1fr);
gap: 5px;
height: 100vh;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
transition: all 0.5s ease;
opacity: 1;
}
.grid-cell {
background-size: cover;
background-position: center;
transition: all 0.5s ease;
cursor: pointer;
border-radius: 10px;
}
<div class="grid-container" id="gridContainer"></div>