JavaScript CSS3

動畫互動網頁程式設計 - 上課教材

動畫互動網頁程式設計 > 課程內容 > 第 06 章 - CSS 圖形變形與動畫

第 06 章 - CSS 圖形變形與動畫

上次更新日期 2020/05/12

大概掌握了 CSS 相關的基礎技能之後,同時也大致能夠知道網頁的方塊如何設定,接下來就是可以來玩一玩一些照片、底圖、特殊用途的圖示特效了! 而要讓網頁變得更生動,視線聚焦的動畫特效、小圖示的移動、文字偏移的特效等等,都可以透過相關的方塊模型來一探究竟~ 不過這些特效的使用也得要注意,不要讓畫面太過混亂。同時,如果覺得有不錯的特效,就寫入類似 overall.css 的統一外部文件吧! 這樣才有辦法持續應用 (記得自己提醒自己,造過得輪子不用重複製造啦!)

學習目標:

  1. 了解多張底圖同時運作的 CSS 設定方式
  2. 開始使用漸變與變形功能
  3. 開始使用 CSS 動畫效果

6.1: 底圖的設置應用

底圖如果做的好,可以達成很多的效果!甚至於,許多的按鈕特效也可以透過兩張底圖來達成效果!而不去考量 CSS 的按鈕功能哩!同時,如果一個網頁要擺兩張底圖的話, 也能夠輕鬆的完成喔!

如果想要做兩張底圖時,可以使用 background-image: url('1st.jpg'), url('2nd.jpg'); (請注意,兩個底圖中間有逗號隔開喔!) 這樣的模樣來設定,同時,後續包括是否要重複?是否要放置在何處等等, 都需要使用到兩個底圖的參數這樣才行!舉例來說,如果我們想要製作出一個偏向夏天的歌曲畫面,標題可以是兩張底圖,或者是兩個圖示的對角線結合。 我們可以這樣玩一玩:

例題 6-1-1: 建立多張底圖的網頁
  1. 先將底下的底圖下載,然後上傳到 /www/images 裡面去: 這個圖檔這個圖檔這個圖檔 (要特別注意副檔名!)
  2. 內文的部份請以 這個檔案內容 來設計。最主要的目的是讓向日葵在左下角,而蜜蜂在右上角, 其他空間則填滿與向日葵相同天空色的底圖。至於歌詞,則填充在中間空白的部份這樣。因此,我們需要讓歌詞存在於一個方塊, 而這個歌詞的方塊則放置在另一個大方塊內,外層方塊就可以用底圖來處理了!
  3. 建立名為 /www/unit06-1-1.html 的網頁檔,這個檔案需要呼叫 overall.css 整體風格樣式檔,然後在 index.html 新增一條連結, 方便點擊查閱資料。
  4. 將剛剛的文字檔內容貼到 body 內,針對外部方塊 (page) 的設定可以設計成這樣:
    • 給予寬、高分別為 800, 600 像素;
    • 先給一簡單的 1px solid gray 的框線,比較好觀察方塊的所在
    • 給予位置為相對位置 (relative)
    • 給予三張底圖,分別為向日葵、蜜蜂與天空色 (就直接按照圖檔檔名的順序)
    • 先查看一下網頁,你會發現底圖的設計比較有趣:
      • 先出現的底圖為優先,後出現的底圖會被影藏,因此網頁只有向日葵,其他兩張圖被覆蓋了
      • 預設為持續重複輸出 (repeat)
  5. 底圖的重新處理:讓天空色一直重複,向日葵與蜜蜂則不予重複
    • 三張底圖中,向日葵、蜜蜂不要重複,但是天空色請重複出現!
    • 查閱網頁,發現到只有天空色與向日葵,蜜蜂不見了。這是因為圖片預設都在原點左上角的緣故,所以蜜蜂被覆蓋了!
    • 給予三張底圖的位置 (background-position),分別為左下方、右上方、左上方
    • 查閱網頁,終於三張底圖都出現了喔!
  6. 針對內部的 pre 這個標記進行如下的設計:
    • 給予寬度為 600 像素,並且給予 1px solid gray 的框線
    • 位置為絕對位置 (absolute),同時這個方塊會緊黏在右方父方塊上 (right:0)
    • 因為是藍底,我們給予白色字型,但是因為會不太明顯,因此建議給予字型陰影,類似 1px 1px 1px black 即可喔!
    • 查閱網頁,若確定正確無誤,請將框線厚度更改為 0 即可。
完成的圖示會有點像底下這樣: 例題的完成示意圖

完成圖示之後,你可以嘗試將 page 這個外層方塊的寬度 (width:1200) 放大看看,你會發現蜜蜂與向日葵的距離被拉長了, 不過向日葵永遠在左下角,蜜蜂永遠在右上角,中間的方塊部份要規劃多大,就可以隨你開心來設計與填充所需要的文字、資料方塊了。

  • 背景填滿的方法

某些情況下,你可能得要將背景整個填滿空間!不是重複,是填滿喔!問題是,你的底圖與方塊的長寬比並不一致,這時該怎麼辦? 基本上,你可以透過 background-size 裡面的屬性值來調整,這個屬性值有幾種設定方式:

  • background-size: Xpx Ypx :意思是底圖的 X 與 Y 的像素。不過因為同時設定兩個,所以可能圖畫的長寬比會被改變,就會變得壓扁或拉長的變形問題。
  • background-size: contain :contain 的意思是,將圖片在方塊裡面放大,直到第一個寬或高充滿方塊為止,因此,可能會有一邊 (寬或高) 會有留白的空間
  • background-size: cover :cover 的意思是,將圖片在方塊裡面放大,直到最後一個寬或高充滿方塊為止,因此可能會有一邊超出方塊之外

這麼講你可能會搞不清楚,我們實際來測試看看就知道了。請使用剛剛上面談到的兩個圖示,就是向日葵與蜜蜂的圖示就好,我們做個圖層, 讓蜜蜂停在向日葵上面吧!

例題 6-1-2: 測試背景填滿的方法,主要為 contain (長邊填滿) 與 cover (短邊填滿) 的用途
  1. 設計思考:使用前一個例題的蜜蜂與向日葵來設計,主要是希望讓『向日葵填滿整個方塊』,然後『蜜蜂停在向日葵上面』的效果。
  2. 建立名為 /www/unit06-1-2.html 的網頁檔,這個檔案需要呼叫 overall.css 整體風格樣式檔,然後在 index.html 新增一條連結, 方便點擊查閱資料。
  3. 建立網頁內容:請撰寫底下的 HTML 碼在 body 標籤內:
    <div class="page1">
    	<img src="images/ex6_1_1b.png" alt="蜜蜂要停在向日葵上" />
    </div>
    <div class="page2">
    	<img src="images/ex6_1_1b.png" alt="蜜蜂要停在向日葵上" />
    </div>
    
    設計完畢之後,先查看一下網頁的顯示結果。
  4. 針對 page1 與 page2 的方塊設定,都設定底下這些屬性:
    • 寬度與高度都是 400 像素,先給一個 1px solid gray 的框線,確認方塊的位置
    • 都給位置為相對位置;
    • 方塊顯示的特性為行內區塊 (inline-block)
    • 都給背景圖為 images/ex6_1_1a.jpg 這一個,且背景不重複
    • 立刻查閱一下網頁,可以發現方塊比底圖還要大,沒有將方塊整個填滿!
  5. 針對 page1 的長邊填滿 (contain) 效果測試:
    • 單獨針對 page1 給予 background-size: contain; 的屬性
    • 在 page1 裡面的 img 給予 (1)絕對位置 (2)距離左側、上方分別為 200px 與 70px的距離
    • 做完請立即查閱一下網頁的顯示效果
  6. 針對 page2 的短邊填滿 (cover) 效果測試:
    • 單獨針對 page2 給予 background-size: cover; 的屬性
    • 在 page2 裡面的 img 給予 (1)絕對位置 (2)距離左側、上方分別為 250px 與 80px的距離
    • 做完請立即查閱一下網頁的顯示效果
完成的圖示會有點像底下這樣: 例題的完成示意圖

使用 contain 或 cover 都有一些無法克服的問題,不過,至少你不用去修改圖片,也不用因為得要調整寬高導致長寬比變形的問題!

6.2: 圖片的滑鼠特效與漸變特性 (transition/transform)

某些網站會有一些特定的方塊來展示新聞或產品的效果,通常會是一個方塊上半部有照片,下半部有文字說明這樣。 舉例來說,底下這個新聞網站,就會有這樣的方式:

那該如何設計出類似如此的畫面呢?其實也不難,你只要 (1)設計出一個方塊 (2)將圖片與文字寫入方塊內 (3)讓圖示使用類似 width:100% 或 height:100% 之類的方式填滿 (4)最終讓文字緊黏在方塊最下方,並且給予適當的透明度,這樣應該就能夠達成需求了! 如果有需要特效,那是後面章節再來談到的,這裡先來玩一玩基本圖示即可。

例題 6-2-1: 嘗試制定一個自己未來會持續用到的特殊方塊應用
  1. 設計思考:如同上面的新聞網站,其新聞畫面與標題都是固定的,可以方便未來直接將圖片、文字填入, 就可以具有一致性的整體風格了!
  2. 檔案處理: 請將 這個圖檔這個圖檔 兩個圖檔下載後,上傳到 /www/images 目錄內。
  3. 建立名為 /www/unit06-2-1.html 的網頁檔,這個檔案需要呼叫 overall.css 整體風格樣式檔,然後在 index.html 新增一條連結, 方便點擊查閱資料。
  4. 網頁文字內容處理:使用 這個檔案內容,將內容貼到網頁的 body 內
  5. 針對 mypro 這個方塊的設計,我們希望他是一個 300x300 像素的方塊 (你也可以自己調配成自己喜歡的比例),所以:
    • 寬高設定都為 300 像素,且先給予 1px solid gray 的框線,以確認位置所在。
    • 位置使用相對位置
    • 顯示的特性使用 inline-block ,讓方塊可以在同一行出現。
    • 超出方塊的內容部份將會被隱藏
    • 背景請使用輻射漸層,使用的方式為:
      background: radial-gradient(red, yellow, green);
    • 這時先查看一下網頁,你會發現圖片太大,所以很多部份都被隱藏起來不見了!
  6. 針對 mypro 內部的圖片設計:
    • 針對 mypro 內的影像 (img) ,設定寬度為 100% 與高度都是 100%
    • 增加一個 CSS 參數:『 object-fit: cotain 』來讓圖片自動填滿!
  7. 在 mypro 內的文字 (p) 的部份,相關的設計為:
    • 方塊的寬度為 100%,而高度先設定 50 像素測試一下文字框
    • 這個方塊的外部留白設定為 0 ,讓這方塊與父元素之間可以緊密貼合,但內部留白的上方設定 10 像素
    • 位置設定為絕對位置,且靠下方的框線對齊貼合
    • 文字設定 14 點字、置中對齊、行高為 1 倍、且給文字陰影 1px 1px 1px gray 這樣的文字項目設定
    • 給予透明的背景色 (rgba),為白色且有 70% 的透明度
  8. 滑鼠特效:當滑鼠滑進這個方塊時,方塊內的影像 (img) 寬度與高度會放大為 120%
完成的圖示會有點像底下這樣: 例題的完成示意圖

上面這個範例中,你可以看到 HTML 的原始碼其實很簡單,比較有幫助的應該就是 mypro 相關的 CSS 設定而已。 如果你規劃出一版自己喜歡的版型之後,加到 overall.css 裡面去,未來就又能夠直接使用這些方塊,並放置到你的產品網頁當中囉! 另外,我們在方塊內的圖片使用了一個很神奇的設定,稱為 object-fit 這個項目,這個項目其實跟我們之前 background-size 非常類似! 只是,圖片必需要設定長與寬 (width, height) 的屬性後,才能夠使用這個項目!

  • object-fit:用來設計圖片填滿固定範圍大小的特性,主要的項目有:
    • contain :長邊填滿,所以可能會有留白的部份
    • cover :短邊填滿,所以可能會有部份內容被隱藏
    • fill :依據設定的長寬去拉長,會有變形的問題。這個項目是預設值!
    • none :不變更圖片的尺寸
    • scale-down :過大的圖片才縮小 (contain),若圖片原本就很小,那就不放大。
  • 滑鼠特效的漸變功能

剛剛的圖片是突然的放大,看起來效果不是很好。能不能模擬網路上的漸變特性,讓圖片緩慢的變大呢?是可以的!透過所謂的 transition 這個屬性來處理即可。 不過這個屬性的值還挺多的~需要注意一下:

  • transition: CSS元素 反應時間 [反應函數 [延遲時間]]:幾個屬性值的意義:
    • CSS元素:大概所有的元素都可以支援~包括寬度、高度、顏色、字體等等,均可以被漸變改變
    • 反應時間:從原本的狀態到後來的狀態總共會花費的時間是幾秒,例如 0.5s 之類的模樣
    • 反應函數:從原先狀態到後來的狀態是如何進行,有線性方式、先快後慢方式,先慢後快方式等等。 不過,基本上的動作其實影響不大,因為秒數如果不夠的話,看不太出來。因此建議可以忽略啦!
    • 延遲時間:延遲一段時間才開始漸變的意思。
例題 6-2-2: 圖片放大使用漸變功能
  1. 將 unit06-2-1.html 另存新檔為 unit06-2-2.html,並在 index.html 新增一個連結,方便點擊查閱
  2. 針對圖片的放大設計:
    • 讓 .mypro img 到 .mypro:hover img 的變化中,讓寬度/高度在 1 秒鐘內漸變完成;
    • 因為有兩個屬性要改變,所以記得要使用逗號隔開兩個屬性 (width 1s, height 1s...)
  3. 針對文字框的漸變設計:
    • 讓 .mypro p 到 .mypro:hover p 的變化中,讓背景色變成完全不透明在 1 秒鐘類漸變完成
完成的圖示會有點像底下這樣: 例題的完成示意圖

transition 不是對任何屬性都會生效喔!例如 display: block 的時候,很多寬高的變化就不會呈現。此時可能得要透過 visibility 的方式來處理, 不要使用 display: none 變成 display:block !否則會失敗!

這個 transition 可以用在很多需要 :hover 的場合喔!會讓你的畫面變得比較多漸變,在使用者角度上,會比較能接受~而不是使用跳動的方式來變化啦!

  • 滑鼠特效的變形功能 (transform)

你可能會看過許多設計師會將圖片重疊在一起,製作出懷舊或者是一些獨特意含的照片。不過,如果單純使用繪圖軟體去實做出這樣的圖示, 那麼未來如果想要修改 (例如抽換照片),那工程就浩大了!有沒有可能透過 CSS 方塊的圖層效果來達成呢?當然是可以的! 只是,首先就得要了解一下如何將方塊『轉個角度』囉!

要將方塊轉個角度,可以透過 transform 這個屬性來處理。這個屬性有很多的屬性值:

  • transform: rotate(Ndeg):讓這個元素依據元素的中心點,順時針轉 N 度角 (一圈為 360 度角)。
  • transform: translate(Xpx[, Ypx]):最少需要一個屬性值,就是 X 水平方向的位移,向右為正,向左為負。若需要同時更動兩個,就給予兩個數值。 例如要往右下方個別移動 30 個像素,那就是『 transform: translate(30px, 30px) 』
  • transform: scale(X,Y):X 與 Y 是『倍數』,1 代表不變,小於 1 則是縮小,大於 1 則是放大!
例題 6-2-3: 圖片旋轉的滑鼠特效
  1. 將 unit06-2-2.html 另存新檔為 unit06-2-3.html,並在 index.html 新增一個連結,方便點擊查閱
  2. 針對圖片的旋轉滑鼠效果
    • 將 .mypro:hover 內的 width 與 height 設定取消
    • 承上,將它改為『 transform: rotate(360deg); 』這樣的旋轉樣式
    • 讓漸變改為 transform 項目,且在 1 秒鐘內漸變完成。

接下來,你只要將滑鼠移動到方塊上面,呵呵!就會看到圖片轉一圈啦!相當有趣!

6.3: CSS 動畫效果 (animation)

剛剛上個小節談到的是透過滑鼠去觸發一些漸變特效,那麼,有沒有可能系統自己會跑這些漸變特效?如果會的話,那不就成為動畫了? 對了!這就是 CSS3 的動畫特效囉!但怎麼做動畫特效呢?就跟剛剛前一小節一樣啊,你得要規劃怎麼改變顯示的狀態才行! 所以,就得要有一個特別的項目,稱為 @keyframes 的項目去設計動畫的動作才行!

  • @keyframes animation_name { 動作 }:建立一個名為 animation_name 的動畫特效。
  • 只有開始與結束兩個畫格的動畫設計

在上面的 {動作} 中,主要的動作寫法有兩種,一種是僅有開始跟結束兩種動作,一種則是有時間性的帶入不同的動作。先來設計一下只有開始跟結束的動作項目:

@keyframes demo1 {
	from { transform: rotate(0deg); }
	to   { transform: rotate(360deg); }
}

完成動作設計後,再來就是要將動畫寫入要動作的那個 div 裡面囉!主要需要的項目有:

  • animation-name: 名稱:就是那個 @keyframes 後面接的名稱項目
  • animation-duration: Ns:幾秒類必須要跑完這個動畫的意思
  • animation-timing-function: 預設是 ease 模式,你也可以改成 linear 或其他模式。不過建議保留預設值即可。
  • animation-iteration-count: {N|infinite}:這個動畫跑幾次?可以填寫次數,也能夠使用 infinite 無限次循環!
  • animation-direction: {normal|reverse|alternate|alternate-reverse}:這個動作執行的順序, 包括{正常順序|反向順序|1,3,5是正常2,4,6是反向|1,3,5是反向,2,4,6是正向},如果你的動作開頭與結尾並沒有連續,可以使用 alternate 看看。
例題 6-3-1: 設計一個可以自動旋轉的小小動畫
  1. 設計思考:讓原本 unit06-2-3.html 裡面透過滑鼠旋轉的效果,可以不必經由滑鼠,而自行旋轉,形成一個小動畫。
  2. 先將 unit06-2-3.html 另存新檔為 unit06-3-1.html,然後在 index.html 裡面新增一個連結,方便點擊查閱。
  3. 取消漸變特效等功能:
    • 先取消所有的 :hover 設計,直接從網頁內容刪除
    • 取消所有的 transition 的漸變設計
  4. 建立一個名為 myrotate 的動畫,這個動畫的設計是:
    • 開始 (from) 的狀態是 transform: rotate(0deg)
    • 結束 (to) 的狀態是 transform: rotate(360deg)
  5. 將這個動畫加入到 .mypro img 的設計中:
    • 動畫名稱為 myrotate
    • 動畫執行 1 秒鐘結束
    • 動畫永遠執行 (infinite)
    • 動畫的運作方式請使用 alternate 來實施

如上所示,設計完成之後,原本需要滑鼠支援的旋轉效果,就可以立即自己轉動起來!相當活潑!如果你的畫格不只一個呢? 就透過底下的方案來處理了:

@keyframes demo1 {
	  0%  { action1; }
	 25%  { action2; }
	 50%  { action3; }
	100%  { action4; }
}

6.4: 課後作業

請參考下圖以及下面的說明來設計你的作業 (動畫設計)

  • 作業檔名請取名為 /www/hw06.html,同時在 index.html 上面增加一條連結,方便老師查閱資料。
  • 先參考 unit06-1-1.html 的內容,拿該檔案出來進行修改即可。
  • 建立一個名為 myani 的動畫,這個動畫的設計至少需要為:
    • 開始 (0%) 的背景圖位置 (background-position:) 保留原樣抄寫下來
    • 最終 (100%) 的背景圖位置,中間的蜜蜂位置填寫 center center,讓牠飛到畫面正中央停下來
    • 進階:如果能夠設計出多個網格的變動,不是只有 0 與 100% 而已的話,更好喔!讓蜜蜂到處飛的意思! 也能夠透過 transform 設計 scale 大小,讓蜜蜂飛得有『遠近』的感覺,更好!
  • 將這個動畫加入到 .page 的設計中:
    • 動畫名稱為 myani
    • 動畫執行 3 秒鐘結束
    • 動畫永遠執行 (infinite)
    • 動畫的運作方式請使用 alternate 來實施

例題的完成示意圖