使

使用 CSS 和 JS 制作 3D 爬行者头部动画!

2025-06-07

使用 CSS 和 JS 制作 3D 爬行者头部动画!

我目前正在编写一个基于 Minecraft 宇宙的 Web 应用程序。这是
我在 dev.to 上发表的第一篇文章(我很荣幸),我将与大家分享我是如何用一个 3D 爬行者头部动画来实现这个酷炫效果的,它没有用到任何库,只用了 CSS 和原生 JS

本教程分为两部分:

  • 爬行者头部建模
  • 使用 JavaScript 制作模型动画

对于本教程,我使用ES6 语法CSS 变量

3D爬行者头部建模

这项工作的第一步是创建苦力怕的头部模型。对我来说,这很简单,类似于创建立方体模型。我使用了以下两种资源:

  • 爬虫的脸,face.png
  • 他的头部侧面,side.png

替代文本
替代文本

立方体的每一面都由一个img标签表示,并嵌套在一个div元素中,这里#creeper

<div id="creeper">
    <img src="face.png" class="side front" />
    <img src="side.png" class="side back" />
    <img src="side.png" class="side top" />
    <img src="side.png" class="side bottom" />
    <img src="side.png" class="side left" />
    <img src="side.png" class="side right" />
</div>
Enter fullscreen mode Exit fullscreen mode

在 CSS 中,默认情况下,你可以基于 X 轴和 Y 轴在二维空间中定位 HTML 节点。因此,所有元素都是平面的。
二维空间

就我而言,我想在网页中建模一个 3D 对象。所以我们需要更改 CSS 的默认行为!为此,只需在 CSS 中指明要将元素放置在 3D 空间中即可:

:root {
    --size-creeper: 128px;
}
#creeper {
    width: var(--size-creeper);
    height: var(--size-creeper);
    /* the magic happens here */
    transform-style: preserve-3d;
}

Enter fullscreen mode Exit fullscreen mode

现在,我可以#creeper基于 X、Y、Z 轴精确放置每个子元素了。以下是放置立方体顶面的示例:

.side {
    position: absolute;
    width: var(--size-creeper);
    height: var(--size-creeper);
}
.top { transform: rotateX(90deg) translateZ(calc(var(--size-creeper) / 2)); }
Enter fullscreen mode Exit fullscreen mode

以下等距视图可以帮助您了解物体在 3D 空间中的位置以及如何进行旋转、平移和缩放:
三维空间

我给元素添加了一个动画,#creeper看看所有元素是否都定位正确!更多详情,可以查看代码:

制作苦力怕头部的动画

你可以在 codepen.io 上找到一些很棒的动画。我最近看到的作品之一是这个:https://codepen.io/jhojann/pen/weKBxV ?page=3 。我打算从这个作品中汲取一些灵感,根据鼠标的位置来制作爬行者头部的动画。我们来写一些 JavaScript 代码吧!我设想我的函数签名是这样的:

const animate = (element, options = {}) => {
    ...
}
Enter fullscreen mode Exit fullscreen mode
  • element是你想要动画的 HTML 元素
  • options如果您想更改动画的参数,这将很有用。

让我们编写这个函数。我首先需要获取爬行者头部中心原点的精确位置。为了获取这些值,我使用了getBoundingClientRecton #creeper

const characterRect = element.getBoundingClientRect()
const originX = elementRect.left + elementRect.width / 2
const originY = elementRect.top + elementRect.height / 2
Enter fullscreen mode Exit fullscreen mode

太棒了,现在我们得到了头部的精确原点。下一步是将光标的位置与 X 轴和 Y 轴的旋转绑定在一起。我假设当光标精确位于原点时,X 轴和 Y 轴的旋转应该等于0deg。对于监听器,我设置了如下内容:

// define default params 
options = Object.assign({}, { maxAngleX: 30, maxAngleY: 30 }, options)
// Re-maps a number from one range to another.
const map = (value, low1, high1, low2, high2) => low2 + (high2 - low2) * (value - low1) / (high1 - low1)
const follow = e => {
  try {
    const width = document.body.clientWidth
    const height = document.body.clientHeight
    // Support of smartphone/tablet
    const clientX = e.clientX || e.touches[0].clientX
    const clientY = e.clientY || e.touches[0].clientY
    const decY = map(clientY - originY, -height / 2, height / 2 , -options.maxAngleY, options.maxAngleY)
    const decX = map(clientX - originX, -width / 2, width / 2 , -options.maxAngleX, options.maxAngleX)
    element.style.transform = `rotateX(${-decY}deg) rotateY(${decX}deg)`
  } catch(e) {}
}
Enter fullscreen mode Exit fullscreen mode

现在,让我们用这个 my 函数绑定鼠标和触摸事件handle

document.body.addEventListener('mousemove', handle)
document.body.addEventListener("touchmove", handle, false)
Enter fullscreen mode Exit fullscreen mode

animate最后一步是在页面加载时调用我们的函数:

document.addEventListener('DOMContentLoaded', _ => {
    followCursor(document.querySelector('#creeper'))
})
Enter fullscreen mode Exit fullscreen mode

这是最终结果(移动光标查看动画):

希望你喜欢这篇文章。我也乐于接受任何改进。我不是设计师,只是一个喜欢编码和创造酷炫东西的人!

文章来源:https://dev.to/mcdostone/animating-a-3d-creepers-head-in-css-and-js--2j6a
PREV
使用 Typescript 在 React 中传递 props 直接从 props 中获取 处理对象 将相同的 prop 传递给多个组件
NEXT
VSCode 和“Dev Containers”实践 “Remote - Containers”扩展 如何创建我的第一个 Dev Container 将项目作为 Dev Container 打开