使用clip-path將 GIF 繪製成跳動的字母

2023-07-20 12:12:04

前言

之前看到過一個有趣的CSS效果,今天我們也來實現一遍,將動圖GIF通過clip-path繪製成一個個跳動的字母。

效果如下:

GIF隨便找的,嗯?這不是重點,重點是下面的實現過程,別被GIF吸引了。

如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公眾號首發,關注 前端南玖 第一時間獲取最新文章~

繪製字母

這是該效果的最重要部分,使用clip-path來繪製對應的字母。

MDN上對clip-path的定義如下:

使用裁剪方式建立元素的可顯示區域。區域內的部分顯示,區域外的隱藏。

我們先來繪製一個字母,以字母U為例,因為這個繪製過程也有一個過渡動畫,所以我們需要繪製兩條路徑兩條路徑必須具有相同數量的點

這就是字母U過度動畫的開始與結束的路徑。

它對應的clip-path程式碼如下:

.u {
  clip-path: polygon(
    0 0,
    0 100%,
    100% 100%,
    100% 0,
    84% 0,
    61% 0,
    41% 0,
    19% 0
  );
}

/* hover */
.container:hover .u {
  clip-path: polygon(
    0 6%,
    5% 100%,
    96% 88%,
    98% 3%,
    71% 5%,
    71% 62%,
    31% 68%,
    25% 0
  );
}

這個路徑也不必擔心不會寫,可以直接通過工具clippy生成,非常方便,其它字母都可直接從這生成對應的繪製路徑

現在我們就來實現這個字母的clip-path以及動畫

<style>
  body {
    width: 100vw;
    height: 100vh;
    background: #000;
  }
  .container {
    --duration: 700ms;
    --ease: cubic-bezier(0.16, 1, 0.3, 1);
    max-width: 400px;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    margin: 10px auto;
  }
  .letter {
    width: 80px;
    height: 80px;
    background: salmon;
    transition: clip-path var(--duration) var(--ease);
  }
  .u {
    clip-path: polygon(
      0 0,
      0 100%,
      100% 100%,
      100% 0,
      84% 0,
      61% 0,
      41% 0,
      19% 0
    );
  }

/* hover */
.container:hover .u {
  clip-path: polygon(
    0 6%,
    5% 100%,
    96% 88%,
    98% 3%,
    71% 5%,
    71% 62%,
    31% 68%,
    25% 0
  );
}
</style>
</head>
<body>
    <div class="container">
        <div class="letter u"></div>
    </div>
</body>

來看看效果:

是不是有點感覺了,少了鹿晗差點感覺?別急著就給你加上。

新增背景

直接給這個div加上gif背景行不行?直接新增當然也可以,但想要給他加點合成虛化的效果,這裡就可以使用mix-blend-mode來實現

MDN上對mix-blend-mode的定義如下

描述了元素的內容應該與元素的直系父元素的內容和元素的背景如何混合。

新增程式碼:

.letter::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  user-select: none;
  background-image: url("https://img.soogif.com/xiOE4Hs23bEoQVgN15NOtTUJ7cxFeExY.gif");
  background-position: 50% 0%;
  background-size: cover;
  mix-blend-mode: soft-light;
}

效果如下:

新增搖晃的動畫

這個就比較簡單了

@keyframes letter {
  25%  { transform: translate(-5%,  5%) scale(1.05) rotate(-5deg) }
  50%  { transform: translate( 5%, -2%) rotate( 2deg) }
  75%  { transform: translate(10%,  0%) scale(1.02) rotate( 8deg) }
  100% { transform: translate( 0%, -5%) rotate( 4deg) }
}

@keyframes dance {
  100% { transform: scale(1.25) }
}

現在的效果如下:

新增變色

為了更好的看到效果,這裡又新增了幾個字母,並生成了對應的clip-path

.u {
  clip-path: polygon(0 0, 0 100%, 100% 100%, 100% 0, 84% 0, 61% 0, 41% 0, 19% 0);
}
.container:hover .u {
  clip-path: polygon(0 6%, 5% 100%, 96% 88%, 98% 3%, 71% 5%, 71% 62%, 31% 68%, 25% 0);
}
.a {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
.container:hover .a {
  clip-path: polygon(46% 2%, 57% 0, 100% 83%, 0% 100%);
}
.s {
  clip-path: polygon(0% 0%, 51% 0, 100% 0, 100% 100%, 50% 100%, 0 100%);
}
.container:hover .s {
  clip-path: polygon(100% 0, 60% 40%, 100% 70%, 0 100%, 40% 60%, 0 30%);
}
.d {
  clip-path: polygon(0% 0%, 0% 100%, 25% 100%, 60% 60%, 60% 60%, 40% 40%, 40% 40%, 25% 100%, 100% 100%, 100% 0%);
}
.container:hover .d {
  clip-path: polygon(6% 2%, 0 93%, 31% 100%, 27% 30%, 54% 34%, 61% 59%, 21% 72%, 31% 100%, 100% 74%, 76% 11%);
}
.p {
  clip-path: polygon(0% 0%, 0% 100%, 25% 100%, 49% 56%, 49% 46%, 49% 47%, 19% 56%, 25% 100%, 100% 100%, 100% 0%);
}
.container:hover .p {
  clip-path: polygon(5% 3%, 2% 100%, 33% 92%, 24% 18%, 71% 25%, 57% 46%, 25% 41%, 19% 66%, 90% 55%, 100% 0);
}

此時效果是這樣的:

此時跟我們最終的效果就差一個變色了,變色其實也很簡單,在關鍵幀中三種顏色之間不斷進行轉換,#a6e630 #f5e82f , 和#4cb8f5

.container:hover .letter {
  animation: calc(var(--duration) * 2) calc(var(--i) * (var(--duration) / -3)) steps(3, end) alternate infinite;
  animation-name: colors, letter;
}

.container:hover .letter::before {
  animation: dance calc(var(--duration) * 2) calc(var(--i) * (var(--duration) / -3)) steps(3, end) infinite;
}

@keyframes colors {
  0%   { background-color: #a6e630 }
  50%  { background-color: #f5e82f }
  100% { background-color: #4cb8f5 } 
}

此時最終的效果就完成了~