浏览网站时发现一个比较有趣的文字效果,实现起来也不是很复杂,所以尝试自己复刻一下,功能简单,但是在复刻的过程中,一点点调试参数,不断的切换思路,有的思路比较复杂,有的思路比较简单,甚至一个hover就能做一个差不多的效果,实现的结果很简单,但是过程很有趣。
效果
准备工作
创建一个主文字图层,再创建几个copy的文字图层,使用text-shadow
将文字描上黑色的边,给copy图层填充不同的颜色,并设置不同的缩放效果,使用transform
的3d缩放,设置景深为500,并依次修改z轴
的数值,达到近大远小的效果,在网上找一款比较可爱胖嘟的 字体
<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>
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
点,那就用屏幕中心坐标-鼠标坐标
得到平面直角坐标系
const width = document.body.offsetWidth
const height = document.body.offsetHeight
// 屏幕中心坐标 或者获取h1元素的中心坐标,h1居中,中心坐标和屏幕中心坐标一样的
const center = new Vector2(width / 2, height / 2)
center
为中心坐标,在mouseMove
方法中得到mouse坐标,并计算出鼠标在四个象限中的坐标
const mouse = new Vector2(x, y);
// 以文字中心为中点,计算出鼠标所在位置
const vector2 = center.clone().sub(mouse)
修改文字元素
通过鼠标的位置,改变元素的transform
属性,可以通过设置不同属性的值,改变不同的样式
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 打造游戏小场景(拾取武器、领取任务、刷怪)