前言

筆者某天在Pinterest上看到一個活靈活現的搜尋鈕

https://i.imgur.com/1QkC5Bm.gif

資料來源:https://www.pinterest.com/pin/835699274601563017/

如果僅僅考量做為轉場動畫出現的話…

那麼今天練習用CSS的 @keyframes 動畫屬性做出類似的效果吧 😀

最後的成果是這樣~

https://imgur.com/KO9FLuq.gif


分解動畫順序

  1. 滑鼠移入游標改變並開始動畫
  2. 手柄彈跳一下之後縮進去
  3. 鏡框拉長
  4. 兩條線從框右側出現並交錯成叉叉 (還彈了一下呢!)
  5. 從左側滑出一段文字

HTML建立框架

https://imgur.com/rcVoTfq.jpg

https://imgur.com/FA9YUFv.jpg

https://imgur.com/APyNJvq.jpg

  • wrapper 作為背景
    • box 用來包住放大鏡的素材
      • glass 放大鏡的鏡框
      • handle 放大鏡的把手
      • cross 最後出現的兩條交叉線(最後放大才出現,所以開頭會先隱藏起來)

CSS樣式設定

漸層背景圖-gradient屬性

.wrapper{
height: 100%;
background: linear-gradient(to top, #ffcccc 12%, #ccff99 90%);
}

漸層背景參考網站https://www.w3schools.com/colors/colors_gradient.asp

(可以自由設定漸層角度、程度跟顏色,最後還可以直接複製貼上~)

https://imgur.com/eAQsG7n.jpg

設定包住放大鏡的div

.box{
    width:300px;
    height: 70px;
    display: block;

    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(-50%,-50%);

}

為了方便展示就先用absolute定位在畫面的正中央
但定位會以物體的左上角為參考點,因此會有所偏移 (如黃色長方形)

利用translate(-50%,-50%)進行矯正
(translate是以物體本身的寬高進行移動~ -50%就是向左以及向上移動自身一半的距離)

設定放大鏡的外型~

鏡框glass

.glass{
    width:50px;
    height:50px;
    border: 5px solid #FFF;
    border-radius: 25px;
    padding: 5px 15px;

    position: absolute;->定位在框的正中間
    top:50%;
    left: 50%;
    transform: translate(-50%,-50%);

    overflow: hidden;---->為了接下來要滑入的字在進框前是看不見的
    cursor:pointer;---->游標移入會改變樣式
}

把手handle

.handle{
    width: 25px;
    height: 5px;
    background-color: #FFF;
    border-radius: 20px;

    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(17px,13px) rotate(45deg);
    transform-origin: 0;    
}

https://imgur.com/o5PUdat.jpg

我需要手柄的部分等等可以向右下角延伸(rotate(45deg) 並回縮

所以就要利用 transform-origin 定位物件的中心點~

延伸閱讀:CSS沒有極限 – CSS transform-origin

那麼到這邊放大鏡的外框都處理好了!

接下來要來處理動畫的部分囉~


滑鼠移入後開始動畫-hover

手柄伸縮後隱藏

.glass:hover~.handle{
    animation: moving 1.5s forwards cubic-bezier(0, 1.18, 0.89, 1.01);  
}

@keyframes moving{ 
    0%{width: 25px;}
    60%{width: 30px;}
    100%{width: 0px;visibility: hidden;}
}

這邊會選擇使用選擇器"~"是因為handle的範圍不大,導致難以碰觸到

就改以碰觸到鏡框來觸發handle動畫了~

慢動作看起來是這樣子

https://imgur.com/4jSsILm.gif

鏡框放大

.glass:hover{
    animation: bigger 0.5s 1.5s forwards cubic-bezier(0, 1.18, 0.89, 1.01);
    }

@keyframes bigger{
    0%{width:50px;border-radius: 25px;}
    100%{width:300px;border-radius: 25px;}
}

因為動作在handle之後,動畫就要設定延遲時間1.5s(handle的動畫時間),且希望在動畫結束後維持最後的樣子(forwards)

一般如果想呈現圓形也會用border-radius:50%,但在拉長成框過程中就是從橢圓拉成弧框(效果如下)

我希望的效果 (border-radius: 25px):

https://imgur.com/28HbUoN.jpg

用 border-radius: 50%做出來:

https://imgur.com/OGaAdOM.jpg

框框放大完成後從右側滑入兩條線交叉成叉叉

在這邊用了偽元素:before跟:after來做線~

也是用游標滑入鏡框之後做為開始動畫的標準

因此延遲時間應為框框打開之後才滑入

.cross{
    width: 25px;
    height:25px;
    position: absolute;
    top:50%;
    right: 8px;
    transform: translate(-50%,-50%);
}

.cross:before{
    content:" ";
    width: 25px;
    height: 4px;
    background-color: #FFF;
    border-radius: 20px;

    position: absolute;
    top: 0px;
  left: 3px;
  transform: rotate(-315deg);
    transform-origin:0;
    opacity: 0;--->希望在動畫開始前看不到線條
    transition: width 0.5s linear;
}

.cross:after{
    content:" ";
    width: 25px;
    height: 4px;
    background-color: #FFF;
    border-radius: 20px;
    position: absolute;
    top: 18px;
  left: 3px;
  transform:rotate(315deg);
    transform-origin:0;
    opacity: 0;--->希望在動畫開始前看不到線條
    transition: width 0.5s linear; 
}

.glass:hover~.cross:before{
    animation: slide-1 0.5s 1.2s forwards cubic-bezier(0, 1.18, 0.89, 1.01);                    
}

.glass:hover~.cross:after{
    animation: slide-2 0.4s 1.1s forwards cubic-bezier(0, 1.18, 0.89, 1.01);                
}

@keyframes slide-1{ 
    0%{width: 0px;top: 24px;left: 28px;opacity: 1;}
    60%{width: 35px;}
    80%{width: 23px;}---->先變短再變長會有彈跳的感覺!
    100%{width: 25px;opacity: 1;}
}
@keyframes slide-2{ 
    0%{width: 0px;top: -6px;left: 28px;opacity: 1;}
    60%{width: 35px;}
    80%{width: 23px;}
    100%{width: 25px;opacity: 1;}
}

最後文字從左側滑入

.glass p{
    margin: 0;
    font-size: 20px;
    font-family: 微軟正黑體;
    position: absolute;
    left: -120px;
}

.glass:hover p{
    transition:all 1.5s 1.2s linear;
    position: absolute;
    left: 90px;
}

https://imgur.com/i3JmqA8.jpg

這邊沒有用opacity: 0 可是動畫開始前框外看不到文字耶!?

那是因為在glass放大鏡框那邊用了overflow:hidden呦~所以入框內才會出現

文字進場又相當簡單~沒有前面那邊伸縮彈跳效果,就直接使用hover做效果了

順序在所有東西就定位之後才緩緩進場,就用transition設定進場時間跟延遲時間~


那麼簡單又可愛的小動畫就做完啦!

使用keyframes要注意在不同瀏覽器(注意版本號!)要加上不同前綴

前綴 瀏覽器
-moz- 火狐
-webkit- Chrome跟Safari
-o- Opera Mobile

參考網站:https://caniuse.com/?search=keyframes

https://imgur.com/fmbSUKa.gif