妙用 scale 與 transfrom-origin,精準控制動畫方向

上次發完 難以想象的純 CSS 導航欄下劃線跟隨效果 這篇文章以後,不少朋友找我討論,感嘆 CSS 的奇妙。git

而後昨天,羣裏一位朋友問到了一個和這個效果比較相似的效果,問如何github

將下面這個動畫的下劃線效果,從左進入,右邊離開修改成從上方進入,下方離開函數

描述很難理解,看看本來的效果:動畫

tsorigin

難點所在

第一眼看到這個效果,個人心裏毫無波瀾。覺得只是簡單的一個下劃線 hover 效果,通過友人提醒,才發現,這個動畫效果中,下劃線是從一端進入,從另一端離開的。並且,這個 hover 動畫是純 CSS 實現的。ui

youqu

先不考慮上面說的修改需求,先想想,若是就是還原上述效果,僅僅使用 CSS,該如何作呢?spa

還原效果

嗯,正常而言,咱們一個 hover 效果,可能就是從哪裏來,回哪裏去,大部分的應該是這樣的:code

xxx

CodePen Demo -- 從哪裏來,回哪裏去orm

如今,難點就在於如何在 hover 離開的時候,改變更畫行進的方向cdn

下面咱們將一個 hover 動畫分解爲 3 個部分:blog

  1. hover 進入狀態
  2. hover 停留狀態
  3. hover 離開狀態

可是,對於一個 hover 效果而言,正常來講,只有初始狀態,和hover狀態兩種。可能咱們的代碼是這樣:

div {
    xxxx...
}

div:hover {
    xxxx...
}

複製代碼

對於一個 hover transition 動畫,它應該是從:

  • 正常狀態 -> hover狀態 -> 正常狀態 (三個步驟,兩種狀態)

因此,必需要有一種方法,可以使得 hover 動畫的進入與離開產生兩種不同的效果,實現:

  • 狀態1 -> hover狀態 -> 狀態2 (三個步驟,三種狀態)

實現控制動畫方向的關鍵點

因此,這裏的關鍵點就在於(劃重點):

使得 hover 動畫的進入與離開產生兩種不同的效果

接下來,也就是本文的關鍵所在,使用 transform: scale() 以及 transform-origin 實現這個效果。

transform: scale() 實現線條運動

transform: scale 你們應該都很熟悉了,通俗來講是用於縮放,用官方的話說,就是:

CSS 函數 scale() 用於修改元素的大小。能夠經過向量形式定義的縮放值來放大或縮小元素,同時能夠在不一樣的方向設置不一樣的縮放值。

這裏咱們使用 transform: scaleX(0)transform: scaleX(1) 來改變線條的顯示與隱藏,它的 CSS 代碼簡單來看,多是這樣:

div {
    position: absolute;
    width: 200px;
    height: 60px;
}

div::before {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 200px;
    height: 2px;
    background: deeppink;
    transition: transform .5s;
    transform: scaleX(0);
}

div:hover::before {
    transform: scaleX(1);
}

複製代碼

scale

CodePen Demo -- transform: scaleX(0) 與 transform: scaleX(1)

嗯?爲何是要用 transform: scale() 來實現線條的動畫?由於它能夠配合 transform-origin 實現動畫的不一樣運動方向:

transform-origin 實現線條運動方向

transform-origin 讓咱們能夠更改一個元素變形(transform)的原點,transform-origin 屬性可使用一個,兩個或三個值來指定,其中每一個值都表示一個偏移量。 沒有明肯定義的偏移將重置爲其對應的初始值。

本效果最最最重要的地方就在於這裏,咱們使用 transform-origin 去改變 transform: scale() 的原點實現線條運動的方向。

  1. 咱們給線條設置一個默認的 transform-origin 記爲狀態1
  2. hover 的時候,設置另一個不一樣的 transform-origin, 記爲狀態2

因此,固然咱們 hover 的時候,會讀取狀態2transform-origin,從該原點開始放大至 scaleX(1),hover 離開的時候,會讀取狀態1transform-origin,從scaleX(1)狀態縮小至該原點。

嗯,CSS代碼大概是這樣:

div {
    position: absolute;
    width: 200px;
    height: 60px;
}

div::before {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 200px;
    height: 2px;
    background: deeppink;
    transition: transform .5s;
    transform: scaleX(0);
    transform-origin: 100% 0;
}

div:hover::before {
    transform: scaleX(1);
    transform-origin: 0 0;
}
複製代碼

這裏,咱們巧妙的經過 hover 狀態施加了一層新的 transform-origin ,讓動畫的進入與離開產生了兩種不一樣的效果,兩個不一樣的方向。

如此一來,也就順利實現了咱們想要的效果,撒花:

torigin

CodePen Demo -- transform-origin妙用

注意,這裏使用了 transform-origin 去改變 transform: scale() 的原點實現線條運動的方向,而沒有藉助諸如 position 位移,transform: translate(),或者 margin 等位置屬性去改變線條所在的位置。

因此,有趣的是,線條其實沒有產生過任何位移,這裏其實也是障眼法,讓它看上去,它好像在移動。

拓展延伸

嗯,有了上述方法,也就是 transform: scale() 配合 transform-origin ,咱們能夠開始隨意改變更畫的初始與結束狀態了。把他們運用到其餘效果之上,簡單的幾個示意效果:

othertraorigin

CodePen Demo -- transform:scale 配合 transfrom-origin 控制動畫方向

值得注意的點

還有幾個點是比較有意思的,你們能夠嘗試嘗試,思考思考:

  • 嘗試改變兩種狀態的 transition-timing-function 緩動函數,可讓動畫更加流暢具備美感;
  • 注意一下,線條的 transition 設置的是 transition: transform .5s 而不是 transition: all .5s,體驗一下兩種寫法所產生的不一樣效果。

最後

本方法我我的最先見於 Css菜單懸停效果。若是你有更好的方法歡迎提出共同探討。

更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

好了,本文到此結束,但願對你有幫助 :)

若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

相關文章
相關標籤/搜索