記一個頭像高光動畫的CSS實現

蘇里發表於2019-04-13

前言

久違的,又抽時間寫個部落格(づ ̄3 ̄)づ╭❤~~

今天想分享一個小動畫的實現頭像跳動並高光劃過效果展示 大家可以先點進去看看效果~點選頭像觸發動畫效果~

或者直接看兩張圖片示意~全部程式碼貼在文字底部,或者可以點選連結去CodePen

高光在左邊
高光在右邊

思考

這裡的難度在於高光如何實現?這個動畫我不是第一次做了,以為都是用切圖實現,正是因為做過多次,這一次想能不能用純CSS程式碼實現呢?

答案是可以的(●´∀`●)ノ

首先第一步!也是我放棄切圖的第一步!

高光

為了使大家看清楚。我設了黑底,理論上如果切圖的話是透明底PNG。

這裡不探討CSS實現和PNG哪種方式更好~

首先我設計了高光的兩種CSS實現方式~

棄用方案一

實現長方形和顏色漸變background: linear-gradient(90deg, transparent 15%, #fff);後,使其旋轉transform: rotate(?deg);。多出來的部分會被頭像overflow:hidden,所以貌似這個高光就輕而易舉實現了?但是發現難點就在與實際上寬高和旋轉角度如果要和設計稿完全切合的話,需要一定的數學平面幾何計算(而我已經還給老師了...)。

棄用方案二

直接實現一個矩形的顏色漸變,然後實現左上角和右下角的小三角進行遮罩裁切,可惜這方面我的Photoshop功力比CSS功力還好...(CSS裡貌似找不到這個支援:一個元素對另一個元素的遮罩,如果有小夥伴知道可以留言告訴我)

實現

當我正掙扎迴歸於切圖方案時,此時我想起了一個CSS屬性clip-path,大家不妨可以點進這個MDN裡看看這個屬性。關心相容的同學也可以去看看相容情況

MDN文件介紹:clip-path CSS 屬性可以建立一個只有元素的部分割槽域可以顯示的剪下區域。區域內的部分顯示,區域外的隱藏。剪下區域是被引用內嵌的URL定義的路徑或者外部svg的路徑,或者作為一個形狀例如circle().。clip-path屬性代替了現在已經棄用的剪下 clip屬性。

這個屬性十分強大。可以裁切出橢圓形、多邊形、SVG路徑,還可以根據幾何盒子模型來~

很好!我想要的是一個平行四邊形,clip-path: polygon(50% 0, 100% 0%, 50% 100%, 0% 100%);,很輕鬆的實現了~

接下來具體的動畫要求是:300ms頭像變大,500ms高光從左至右邊划過去,300ms頭像縮放至原本大小。

這個可以通過兩個元素的動畫組合實現~ animation: heartbeat 1.1s linear forwards; animation: highlight 1.1s linear forwards;

由於效果需要適當時機主動召喚出現,所以離不開Javascript的幫助啦。這裡的實現方式就是需要效果時新增動畫className,動畫結束後主動移除className~

大家感興趣可以看看程式碼,PS:CSS使用了less的格式~

程式碼

<div class="user-headpic"></div>
複製程式碼
@size: 50px;
.user-headpic {
  position: relative;
  display: block;
  width: @size;
  height: @size;
  background: 
    url("https://user-gold-cdn.xitu.io/2018/10/25/166a8fc6cd14bf6f?imageView2/1/w/180/h/180/q/85/format/webp/interlace/1")
    center/cover
    no-repeat;
  border-radius: 100%;
  border: 2px solid silver;
  overflow: hidden;
  &:after {
    .cube(@size);
    .highlight(@size);
  }
  &.starring {
    animation: heartbeat 1.1s linear forwards;
    &:after {
      animation: highlight 1.1s linear forwards;
    }
  }
}

.cube(@w) {
  content: '';
  position: absolute;
  width: @w;
  height: @w;
}

.highlight(@w) {
  position: absolute;
  width: @w;
  height: @w;
  left: -@w;
  top: 0;
  background: linear-gradient(90deg, transparent 15%,  #fff);
  -webkit-clip-path: polygon(50% 0, 100% 0%, 50% 100%, 0% 100%);
  clip-path: polygon(50% 0, 100% 0%, 50% 100%, 0% 100%);
  z-index: 3;
}

@keyframes highlight {
  0 {
    transform: translateX(-@size);
  }
  27.27% {
    transform: translateX(-@size);
  }
  72.73% {
    transform: translateX(2 * @size);
  }
  100% {
    transform: translateX(2 * @size);
  }	
}
@keyframes heartbeat {
  0 {
    transform: scale(1);
  }
  27.27% {
    transform: scale(1.2);
  }
  72.73% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}
複製程式碼

思考

這個CSS屬性相容性不是很友好。不過本著學習的精神去玩一下也是不錯的,說不定過幾年用的上了哈哈哈~

相關文章