Nintendo Wii 使用 HTML、CSS 和 Javascript 放大动画过渡

问题描述 投票:0回答:1

我想制作一个像 Wii 菜单转换一样的动画,当你点击一个频道时:

Wii 菜单视频(分钟 0:16)

如您所见,窗口放大到频道,然后频道页面打开。通道周围没有任何东西扭曲,这意味着通道组件的尺寸没有增长(我想)。

据说Wii菜单是用HTML编码的,所以应该可以吧?

我尝试使点击的图像随着背景变小而变大,但结果与原始结果相去甚远。另外,我找不到能够做到这一点的框架或库,甚至没有一个具有这样的动画的网站。如果你发现了什么,请告诉我。

javascript html css animation transition
1个回答
0
投票

我使用一些人工智能辅助进行构建。想法是在与网格中单击的单元格相同的位置上创建一个固定位置节点。使用

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>

© www.soinside.com 2019 - 2024. All rights reserved.