3D字体交互效果【国庆特别版】

2,336 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

介绍

我国庆即将开始,我先预热一下整点小效果玩玩。

我们本期要使用scss+js做出一个可以与鼠标交互的3d字体效果,如下图:

VID_20210928_140429.gif

本身并不难做,具体会分为:页面结构,字体样式,鼠标交互三个部分来说明,另外,要说明的是,本次用vite搭建,好了我们要出发咯~

正文

1.页面结构

<div id="app"></div>
<script type="module" src="./app.js"></script>

我们先要在index.html里通过module模式引入主逻辑脚本。

/*app.js*/
import "./css/style.scss"

;(function() {
  let words = [
    "Happy",
    "National",
    "Day"
  ]
  let wordNodes = []
  words.forEach(word => {
    let _div = document.createElement("div");
    _div.className = "text-3d-block";
    _div.innerHTML = word;
    _div.setAttribute("data-text", word);
    wordNodes.push(_div)
    document.getElementById("app").appendChild(_div);
  })
})();

这一步很简单,就是引入样式,然后把Happy National Day三个单词写入页面。注意:这里我们还要给元素的data-text属性附上当前值,为了其伪类在css content中可以获取到值,具体往后看。

2.字体样式

先别着急,我写字体样式之前,先把他们的父容器填充充满,做个背景,在让其中元素水平垂直居中。

#app {
  width: 100%;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  background-image: radial-gradient(
    circle at center center,
    rgb(248, 255, 107),
    rgb(245, 152, 118)
  );
}

微信截图_20210928155826.png

然后,我们再去写字体样式,先用真实内容做底字

$size: 4.5em;
$space: 0.1em;

.text-3d-block {
  font-size: $size;
  font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
  letter-spacing: $space;
  position: relative;
  background: repeating-linear-gradient(
    45deg,
    #aec9e3 0px,
    #ebf4f7 3px,
    #1689e7 3px,
    #000000 2px
  );
  -webkit-background-clip: text;
  color: transparent;
  -webkit-text-stroke: 1px #1689e7;
  white-space: nowrap;
}

这里要注意,我们底字要用背景字,先绘制出条状背景然后background-clip为text做文字填充,如果后面再添加表层,就是用障眼法让用户以为下面有很多层的目的。

微信截图_20210928155811.png

最后,就是在伪类上获取到当前元素的内容,来填充一个字体压在底字之上,且要出现一定量的偏移。

.text-3d-block {
    --x:7px;
    --y:2px;
    // ...
    &:after {
        content: attr(data-text);
        -webkit-text-stroke: 1px #1689e7;
        font-size: inherit;
        position: absolute;
        color: #FFF;
        text-align: center;
        left: 50%;
        top: 50%;
        transform: translate(calc(-50% - var(--x)), calc(-50% - var(--y)));
        z-index: 1;
        letter-spacing: $space;
        width: 100%;
      }
}

这里我们还用要定义x轴与y轴的偏移量,后期做交互会使用到。其他不做赘述。

微信截图_20210928160349.png

现在样式就写的差不多了,可是怎么让他跟鼠标产生交互呢?

3.鼠标交互

/*app.js*/
;(function() {
    // ...
    window.addEventListener("mousemove", e => {
        let x = 14 * e.clientX / window.innerWidth - 7;
        let y = 4 * e.clientY / window.innerHeight - 2;
        wordNodes.forEach(node => {
            node.style.setProperty("--x", -x + "px")
            node.style.setProperty("--y", -y + "px")
        })
    })
})()

我们先要监听鼠标移动事件,计算一个偏移量,偏移系数可以自己拿捏。随后就是利用setProperty去动态改变x,y,从而改变他伪类中的偏移量,达到改变位置的目的。


说到这里就完全结束了,算是炒鸡容易的一类效果,有时间的可以做着玩玩,在线演示

最后祝大家国庆快乐,还剩1天了,大家一定要沉得住气,不说了,我请假先走了~