2024年8月20日 星期二

使用CSS創造影像立體排列動畫效果

 


文/顏怡宏 Bob Yen

只要是參訪過Apple官方網站的朋友,應該都會對Apple眾多產品的各式各樣網頁動態呈現方法感到驚豔,並且想要一窺究竟,但卻不得其門而入。例如在Apple的迷你喇叭HomePod mini頁面中,就會出現一個有趣的動畫,就是一開始只有一個橘色的HomePod mini在畫面中,如下圖。



但是接著產生了動畫,有四個不同顏色的HomePod mini竟然從後面向兩側竄出,形成立體排列的視覺效果,如下圖。



我們首先來剖析一下這個視覺效果的形成技巧,其實就是先將其他四個不同顏色的HomePod mini藏在橘色的HomePod mini後方。順序是先將黃色與藍色的HomePod mini藏在橘色的HomePod mini後方,並且再將黑色的HomePod mini藏在黃色的HomePod mini後方,最後將白色的HomePod mini藏在藍色的HomePod mini後方。

並且讓橘色的HomePod mini圖形保持原來的大小尺寸,再將黃色與藍色的HomePod mini稍微縮小尺寸,如此才能夠不露痕跡的藏在橘色的HomePod mini後方,再依序的將黑色與白色的HomePod mini繼續稍微縮小尺寸,以便能夠完整的分別藏在黃色與藍色的HomePod mini後方。

而當動畫開始呈現時,將其他四個不同顏色的HomePod mini直接定位到固定的地方,而由於在網頁的CSS座標系統中,left屬性就代表橫向的X軸,越向右側數值就越大,越向左側數值就越小,因此造成了向右是正值,而向左是負值的相對座標關係。而top屬性就代表縱向的Y軸,越向下則數值就越大,越向上則數值就越小,因此造成了向下是正值,而向上是負值的相對座標關係。

最後讓橘色的HomePod mini由中心向四週稍微放大尺寸,並且同時放大其他的四個不同顏色HomePod mini的尺寸,由於在後方HomePod mini的尺寸逐漸縮小,因此就形成了具有遠近距離的透視效果,也就營造出立體的感覺。

本範例使用滑鼠滑入事件來觸發動畫,使用五張花卉的圖片來作為動畫的元素,詳細設定如下:

  1. 首先必須要有一個外容器包含五張花卉的圖片,因此在<body>區塊中,將要成為花卉圖片外框的<div>區塊加上id屬性,命名為 id="flowers",再依序利用<img>標籤放入五張花卉圖片,也分別加上id屬性,將第一張花卉圖片命名為 id="flower1",並且依序命名其他四張圖片為id="flower2",id="flower3",id="flower4"以及 id="flower5"。也相對應的以src屬性分別賦予在images子目錄下的flower1.jpg依序到flower5.jpg,其HTML結構如下:

        <div id="flowers">
            <img src="images/flower1.jpg" id="flower1">
            <img src="images/flower2.jpg" id="flower2">
            <img src="images/flower3.jpg" id="flower3">
            <img src="images/flower4.jpg" id="flower4">
            <img src="images/flower5.jpg" id="flower5">
        </div>

    如此設定後,圖片將會以下圖的順序呈現。



  2. 為了方便以後修改數值,因此在本範例中使用了8個CSS的變數,如此只要修改幾個數值,不但可以在後面的CSS區塊中重複使用這些定義好的變數來設定外觀屬性,也可讓後續的變數來參考。因此在<style>區塊中變數的設定如下:

       :root {
            --image-width:300px; /*此行指定圖像的寬度*/
            --image-height:200px; /*此行指定圖像的高度*/
            --image-offsetX:150px; /*此行指定兩側較大圖像X軸的偏移量,先設定向右所以為正值*/
            --image-offsetY:-90px; /*此行指定兩側較大圖像Y軸的偏移量,因為向上所以為負值*/
            --image-scale:0.7; /*此行指定兩側較大圖像的尺寸,設定為小於1,因此是縮小*/
            --image-offsetX1:calc(var(--image-offsetX)*2); /*此行指定後面較小圖像X軸的偏移量為兩側較大圖像的兩倍*/
            --image-offsetY1:calc(var(--image-offsetY)*2); /*此行指定後面較小圖像Y軸的偏移量為兩側較大圖像的兩倍*/
            --image-scale1:calc(var(--image-scale)*var(--image-scale)); /*此行指定後面較小圖像的尺寸繼續縮小相同的倍率*/
            }
  3. 接著設定命名為 id="flowers" 的父代<div>區塊的外觀與動畫設定,以及滑鼠滑入的 hover 行為,再利用這個區塊來包含子物件圖片,並且成為子物件圖形的參考基準,因此在<style>區塊中設定外框區塊的CSS外觀屬性如下:

        body { /*此行選取body標籤*/
                margin : 0px; /*此行指定網頁內容貼齊瀏覽器左上角*/
            }
        #flowers{ /*此行選取外框區塊*/
            position:fixed; /*此行指定圖形外框區塊不會隨著網頁捲動而隨之移動,並且成為子物件圖片的參考基準*/
            margin-left:calc(50vw-var(--image-width)/2); /*此行指定圖形外框區塊在畫面左右居中*/
            margin-top:calc(50vH-var(--image-height)/2); /*此行指定圖形外框區塊在畫面上下居中*/
            width:var(--image-width); /*此行指定圖形外框區塊與子物件圖形寬度一致*/
            height:var(--image-height); /*此行指定圖形外框區塊與子物件圖形高度一致*/
            transition:transform 1s ease-in-out; /*此行指定圖形外框區塊會針對transform 變形屬性進行時間長度1秒鐘的動畫,
             並且會在開始與結束時產生加減速行為*/
            }
        #flowers:hover{ /*此行設定外框區塊滑鼠滑入的hover事件*/
            transform : scale(1.5); /*此行指定滑鼠滑入圖形外框區塊時會將此區塊放大1.5倍,也會連帶使得子物件圖形放大1.5倍*/
            }
  4. 由於在HTML中,子物件圖片是依照先後順序排列,因此可以得知第一個子物件圖片會在最下方,而最後一個子物件圖形會在最上方,因此代表我們不需要去考慮Z軸的z-index屬性問題,排列的覆蓋順序如同下圖所示。



    接著再設定子物件圖形的外觀屬性,在<style>區塊中設定如下:

      #flowers img{ /*此行選取外框區塊內的所有子物件圖形*/
            width:var(--image-width);/*此行指定子物件圖形與外框區塊寬度一致*/
            height:var(--image-height); /*此行指定子物件圖形與外框區塊高度一致*/
            position:absolute; /*此行指定子物件圖形為絕對定址,並由於外框區塊父物件設定為fixed,因此外框區塊父物件將成為參考基準*/
            left:0px; /*此行指定子物件圖形將鎖定在外框區塊父物件的X軸最左側的原點位置*/
            top:0px; /*此行指定子物件圖形將鎖定在外框區塊父物件的Y軸最上側的原點位置*/
            box-shadow:5px 5px 5px black; /*此行指定子物件圖形產生黑色的區塊陰影*/
            border-radius:10px; /*此行指定子物件圖形產生四個角落的圓角弧度*/
            transition:all 1s ease-in-out; /*此行指定子物件圖形會針對transform 變形屬性進行時間長度1秒鐘的動畫,
             並且會在開始與結束時產生加減速行為*/
            }

    因為子物件圖形設定為 position : absolute; left : 0px; top : 0px;,並且外框區塊父物件設定為 position : fixed,因此外框區塊父物件將成為子物件圖形的參考基準,也就是所有的子物件圖形都會貼齊在外框區塊父物件的左上角原點,而重疊在一起,也就完成了子物件圖形隱藏的靜止初始效果,而實際的畫面如下,只會看到一張上下左右都完全置中的圖片而已。



  5. 由於五張花卉圖形子物件,已經分別加上id屬性,將第一張花卉圖片命名為 id="flower1",並且依序命名其他四張圖片為id="flower2",id="flower3",id="flower4"以及 id="flower5"。接著就根據各個子物件圖形的id來設定,當外框區塊父物件被滑鼠滑入的hover事件發生時,個別的子物件圖形移動前往設定的座標,與縮放至設定的大小,在<style>區塊中設定如下:

     #flowers:hover #flower1{ /*此行設定外框區塊滑鼠滑入後,最下方子物件圖形動畫*/
            left:var(--image-offsetX1); /*此行設定X軸座標向右移動兩倍距離*/
            top:var(--image-offsetY1); /*此行設定Y軸座標向上移動兩倍距離*/
            transform:scale(var(--image-scale1)); /*此行設定尺寸等比縮小兩次*/
            }
     #flowers:hover #flower2{ /*此行設定外框區塊滑鼠滑入後,id為flower2的圖形動畫*/
            left:calc(var(--image-offsetX1)*-1); /*此行設定X軸座標向左移動兩倍距離,但是由於 --image-offsetX1是正值,
            因此必須乘上-1,以取得相對應的負值,才會向左移動*/
            top:var(--image-offsetY1); /*此行設定Y軸座標向上移動兩倍距離*/
            transform:scale(var(--image-scale1)); /*此行設定尺寸等比縮小兩次*/
            }
     #flowers:hover #flower3{ /*此行設定外框區塊滑鼠滑入後,id為flower3的圖形動畫*/
            left:var(--image-offsetX); /*此行設定X軸座標向右移動一倍距離*/
            top:var(--image-offsetY); /*此行設定Y軸座標向上移動一倍距離*/
            transform:scale(var(--image-scale)); /*此行設定尺寸等比縮小一次*/
           }
     #flowers:hover #flower4{/*此行設定外框區塊滑鼠滑入後,id為flower4的圖形動畫*/
            left:calc(var(--image-offsetX)*-1); /*此行設定X軸座標向右移動一倍距離,但是由於 --image-offsetX是正值,
            因此必須乘上-1,以取得相對應的負值,才會向左移動*/
            top:var(--image-offsetY); /*此行設定Y軸座標向上移動一倍距離*/
            transform:scale(var(--image-scale)); /*此行設定尺寸等比縮小一次*/
           }
  6. 如此便大功告成,只要將滑鼠滑入圖片上方,便可以用動畫的方式,逐漸呈現出下圖的外觀了。



  7. 建議課程推薦

0 意見:

張貼留言