浏览网站时发现一个比较有趣的文字效果,实现起来也不是很复杂,所以尝试自己复刻一下,功能简单,但是在复刻的过程中,一点点调试参数,不断的切换思路,有的思路比较复杂,有的思路比较简单,甚至一个hover就能做一个差不多的效果,实现的结果很简单,但是过程很有趣。
效果
准备工作
创建一个主文字图层,再创建几个copy的文字图层,使用text-shadow
将文字描上黑色的边,给copy图层填充不同的颜色,并设置不同的缩放效果,使用transform
的3d缩放,设置景深为500,并依次修改z轴
的数值,达到近大远小的效果,在网上找一款比较可爱胖嘟的 字体
html <h1 data-content="waves">waves</h1> <span class="copy copy1">waves</span> <span class="copy copy2">waves</span> <span class="copy copy3">waves</span> <span class="copy copy4">waves</span> <span class="copy copy5">waves</span>
```css body { background-color: #434e5b; h1, h1~[class^="copy"] { font-family: "Lilita One", cursive; text-shadow: -2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000, 2px 2px 0 #000; font-size: 20vw; display: inline-block; width: 100vw; line-height: 1; height: 20vw; color: #e7e7e7; z-index: 50; position: absolute; top: 0; left: 0; bottom: 0; margin: auto; text-align: center; }
span.copy1 {
color: #f24c00;
z-index: 40;
transform: perspective(500px) translate3d(0, 0, -15px);
}
span.copy2 {
transform: perspective(500px) translate3d(0, 0, -30px);
color: #9792e3;
z-index: 30;
}
span.copy3 {
transform: perspective(500px) translate3d(0, 0, -45px);
color: #fc7a1e;
z-index: 20;
}
span.copy4 {
transform: perspective(500px) translate3d(0, 0, -60px);
color: #eda96d;
z-index: 10;
}
}
@font-face { font-family: 'Lilita One'; font-style: normal; font-weight: 900; font-display: swap; src: url(https://fonts.gstatic.com/s/lilitaone/v13/i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2) format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } ```
产生效果如下:
鼠标操作
下面要做跟随鼠标改变copy图层的旋转和位置的改变
绑定window鼠标事件,并获取鼠标所在位置坐标;
const mouseMove = (e: MouseEvent) => {
const x = e.clientX
const y = e.clientY
// 鼠标坐标
const mouse = new Vector2(x, y);
console.log('mouse', mouse);
}
window.addEventListener('mousemove', mouseMove)
这样既算出的鼠标位置的x和y都>0,因为起点在屏幕的左上角,需要改为四象限的坐标值,以文字中心(屏幕中心)为0,0
点,那就用屏幕中心坐标-鼠标坐标
得到平面直角坐标系
typescript const width = document.body.offsetWidth const height = document.body.offsetHeight // 屏幕中心坐标 或者获取h1元素的中心坐标,h1居中,中心坐标和屏幕中心坐标一样的 const center = new Vector2(width / 2, height / 2)
center
为中心坐标,在mouseMove
方法中得到mouse坐标,并计算出鼠标在四个象限中的坐标
```typescript const mouse = new Vector2(x, y); // 以文字中心为中点,计算出鼠标所在位置 const vector2 = center.clone().sub(mouse)
```
修改文字元素
通过鼠标的位置,改变元素的transform
属性,可以通过设置不同属性的值,改变不同的样式
typescript for (let i = 1; i <= l; i++) { // 根据鼠标归一化位置计算出不同的copy图层该在的位置 const span = copys[i - 1] as any span.style.transform = `perspective(500px) rotate(${vector2.x * i * offset}deg) translate3d(0px,${vector2.y * i * offset * 5}px, ${-15 * i}px) skew(${(vector2.y * offset) * i}deg)`; }
为了方便使用
Vector2
在jcode中引入了一个threjs,开发中没必要~~~ 不要吐槽不要学最终效果
历史文章
# three.js 打造游戏小场景(拾取武器、领取任务、刷怪)