使用 CSS 和 JS 制作 3D 爬行者头部动画!
我目前正在编写一个基于 Minecraft 宇宙的 Web 应用程序。这是
我在 dev.to 上发表的第一篇文章(我很荣幸),我将与大家分享我是如何用一个 3D 爬行者头部动画来实现这个酷炫效果的,它没有用到任何库,只用了 CSS 和原生 JS。
本教程分为两部分:
- 爬行者头部建模
- 使用 JavaScript 制作模型动画
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>
在 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;
}
现在,我可以#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)); }
以下等距视图可以帮助您了解物体在 3D 空间中的位置以及如何进行旋转、平移和缩放:
我给元素添加了一个动画,#creeper
看看所有元素是否都定位正确!更多详情,可以查看代码:
制作苦力怕头部的动画
你可以在 codepen.io 上找到一些很棒的动画。我最近看到的作品之一是这个:https://codepen.io/jhojann/pen/weKBxV ?page=3 。我打算从这个作品中汲取一些灵感,根据鼠标的位置来制作爬行者头部的动画。我们来写一些 JavaScript 代码吧!我设想我的函数签名是这样的:
const animate = (element, options = {}) => {
...
}
element
是你想要动画的 HTML 元素options
如果您想更改动画的参数,这将很有用。
让我们编写这个函数。我首先需要获取爬行者头部中心原点的精确位置。为了获取这些值,我使用了getBoundingClientRect
on #creeper
:
const characterRect = element.getBoundingClientRect()
const originX = elementRect.left + elementRect.width / 2
const originY = elementRect.top + elementRect.height / 2
太棒了,现在我们得到了头部的精确原点。下一步是将光标的位置与 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) {}
}
现在,让我们用这个 my 函数绑定鼠标和触摸事件handle
:
document.body.addEventListener('mousemove', handle)
document.body.addEventListener("touchmove", handle, false)
animate
最后一步是在页面加载时调用我们的函数:
document.addEventListener('DOMContentLoaded', _ => {
followCursor(document.querySelector('#creeper'))
})
这是最终结果(移动光标查看动画):
希望你喜欢这篇文章。我也乐于接受任何改进。我不是设计师,只是一个喜欢编码和创造酷炫东西的人!
文章来源:https://dev.to/mcdostone/animating-a-3d-creepers-head-in-css-and-js--2j6a