來做SVG動畫讓蔥油餅翻滾吧! (上):發想素材、將素材引入網頁(直播筆記)

本文翻自 [週四寫程式系列] 來做SVG動畫讓蔥油餅翻滾吧!,若是對文章內容有疑問,或是想要老闆手把手帶你飛,都可以觀看影片詳細內容。

今天老闆要以曾經接手的 台北聲音地景計畫 做為案例,跟大家分享從專案發想、素材準備到 svg 網頁動畫。當初這個專案是做為捷運站音樂的競賽網站,希望透過聲音做為媒介,連結城市的生活空間。客戶為這個專案準備許多環境音素材,提供比賽使用,但僅是把聲音素材提供給參賽者,讓老闆覺得非常的可惜,該如何將這些素材效益最大化,聲音又要如何跟場景的記憶關聯起來,把故事跟企畫更加完善。最後老闆決定結合網頁動畫與聲音,讓使用者觀看網頁時,透過與現場環境的圖象互動,觸發聲音的回饋,讓使用者將環境與聲音做連結,於是有了這樣的專案產生。

目標

本篇文章中,老闆會帶大家完成元件的創作,並在網頁中將元件導入,完成基本的動畫操作,作為下一篇文章的暖身。

  • isometric 創作場景
  • 使用 vue, ajax 將 svg 放進網頁
  • 小試身手﹔操作 svg 元件,賦予簡單的互動與動態

素材準備

有許多方式和工具能夠製作網頁動態畫面,舉凡 css、svg、canvas、Pixi.js 等,但不管哪一種方式製作動畫,場景和演員是不可或缺的,接下來讓老闆分享動畫要使用到的素材發想過程,想看老闆怎麼完成素材,可以跟著前面提供的影片連結,和老闆一起動手操作。

創作工具

Adobe Illustrator (可到官網上選擇免費版,若是常使用也可選擇付費版)

素材收集與發想

這個專案的困難點,是因為捷運站眾多,創作前,需要到各場域中收集足夠的場景資料,才有足夠的資料來作為創作的依據。

引用自電獺少女

在風格方面,老闆選擇以 isometric 作為創作風格,等距視角(isometric)風格也稱為等軸測圖。採用45度視角,沒有消失點,達到平面上模擬 3D 效果,讓人產生有深度的錯覺。最有名的代表遊戲就是紀念碑谷,若是想知道更多相關設計,也可以到 Pinterest 上查詢相關風格的作品。

創作 isometric 作品的時候,可以利用等距網格輔助創作。

等距網格

用 Illustrator 創作時,記得要幫元件群組與命名,讓開發時,能夠快速選取目標套上動畫。

起手式 – 環境與素材載入

環境

影片中老闆是使用 codepen 來做為開發環境,好處是可以直接引入需要的工具,但載入素材時會遇到跨域問題要解決。這邊提供大家在本機開發的方式。

  1. 將開發需要用到的圖片整理到專案資料夾中
  2. 開始撰寫 html ,載入 CDN,這邊會使用到的 CDN 有兩隻,目的分別如下
    • jQuery – 負責將素材導入
    • vue.js -資料綁定畫面

資源載入

完成 html 結構且載入 CDN 之後,我們要準備讓 svg 動起來,這邊也獻上素材,提供給沒有素材的開發者們,可以直接進入開發。

這邊先解說 script 的內容,我們使用 Vue 來做為資料與畫面綁定的套件。宣告 Vue 的方式如下, el 為要將資料綁定在哪個區塊的畫面中,這裡填寫 #app,也就是到時資料會被綁定在 id=”app” 的 div 中。data 的內容為需要綁定的資料。mounted 為 Lifecycle 中的其中一個鉤子,代表已經抓到渲染的對象,且資料已經成功綁定,這個階段就是載入外部素材的最佳時刻,確保我們的導入的資料能夠成功綁定在對應的位置。

在 Vue 中,從元件初始化到註銷的過程中有許多 hook (created, mounted, destroyed…),提供使用者在元件不同階段中,能夠執行不同工作。詳細內容可以參考 官方文件

使用 jQuery 抓資料的方式如以下程式碼,這邊要小心 this 的使用,如果在外面沒有先宣告 vobj 把 this 記下來,直接寫 this.svg = red 會抓不到外層 vue 的實體資料。

var vm = new Vue({
	// 綁定的範圍
	el: '#app',
	// 綁定的資料
  data: {
		scene_door: ''
	},
	// vue 生命函數,資料載入完成後就執行
	mounted() {
		var vobj = this
		$.get('./imgs/scene.svg', function (res) {
			vobj.scene_door= res
		}, 'text')
	}
})

接著要把素材導入畫面了,這邊我們先在 <body></body> 中加入以下程式碼,id=”app” 是給 vue 辨識綁定畫面的位置。這邊可以看到 v-html=”scene_door” ,v-html 是 vue 的模板與法,會將 data 內的 scene_door 用 html 的方式導入。

在實務中,要小心使用,確定是安全的資料才渲染出來,避免使用者塞入惡意程式碼,但因為此專案是使用我們自己製作的內容,不用擔心被惡意攻擊。

<body>
	<div id="app">
		<div class="scene" v-html="scene_door"></div>
	</div>
</body>

成功之後我們會看到, svg 已經備載入到網頁中了,也可以撰寫 css 將畫面置中。

圖片成功引入

先備知識

接下來,藉由以下兩個目標,讓大家熟悉這個專案會頻繁使用到的概念,1. css 選擇器 2. transition

灰色框與神秘的互動區塊

在畫面中可以看到許多灰色的外框,這是老闆設計要來做為使用者觸發動畫偵測範圍。但是總不能讓這些灰框直接在正式專案上顯示吧?這時就得感謝先前在製作素材時,貼心的我們了。若是在製作素材時,有勤勞的為圖層命名,匯出時會提供選項讓大家選擇,現在我們就能直接在寫 css 使用 data-name 的方式去控制對應元件了。

為什麼不使用 id 呢?因為 id 名稱一個網頁只能有一個,為了避免日後撞名字的問題,這邊選擇使用 data-name。

我們使用開發者工具檢查時,可以觀察到老闆提供的素材中,灰框的 data-name 屬性值為 hidden,我們可以在 scss 中加入一些語法將它變成透明的,但是只把它透明度變成0還不夠,還必須幫它加上背景顏色,並在 trigger 加上改變滑鼠游標的語法。讓使用者滑入互動區塊時,藉由滑鼠的改變,提示使用者此區塊是可以互動的。

// 擁有 data-name 屬性,且該屬性的值為 hidden
[data-name='hidden'] {
	opacity: 0;
	stroke: transparent;
  fill: transparent;
}
// 擁有 data-name 屬性,且該屬性開頭的值為 trigger
[data-name*='trigger'] {
	cursor: pointer;
}
觀察滑鼠進出感應區塊的狀態

做個開關模擬網頁剛進入的狀況

畫面的感應區塊完成後,我們接著來製作開關模擬使用者剛進入網頁的狀況。首先先在 data 中新增一個新的變數,並綁定到畫面中的 input 。大家如果想觀察 vue 資料的變化,也可以去下載套件 vue devtool 輔助開發。透過 input 做為開關之後,場景也必須要跟著互動,這邊我們先使用 v-model 綁定資料,並用 v-bind 來綁定場景 class,當監聽到 trigger 為 true 時,程式會動態的幫我們在 .scene 加上 .active。

var vm = new Vue({
	...
	data: {
		trigger: true,
		scene_door: ''
	},
	...
})
<div id="app">
	<!-- v-model 綁定資料 trigger-->
	<input id="trigger" v-model="trigger" type="checkbox">
	<label for="trigger">場景開啟</label>
	<!-- v-bind 動態改變 class -->
	<div class="scene" v-html="scene_door" v-bind:class="trigger? 'active': ''"></div>
</div>

接下來要讓開關與動畫結合,我們希望當打開開關時,三個小島會有時間差的進入場景,這裡我們又再次使用到前面的技巧,使用 data-name 將所有 island 開頭的內容透明度改成0,在外層吃到 active 後輪流進場。要注意的是,svg 不吃 top 屬性,所以這邊我們改使用 translateY 來讓小島有浮起來的效果。透過 transition-delay 設定不同秒數,達成輪流進場的效果。svg 支援的 css 屬性可參考這篇文章。使用到 transition, transition-delay 也可以到 w3c 中深入了解

.active {
    [data-name*="island"] {
        opacity: 1;
        transform: translateY(0px);
    }
}

[data-name*="island"] {
    opacity: 0;
		// 補間動畫屬性 時間
    transition: all .5s;
		// 初始位置往下 30px
    transform: translateY(30px);
}
[data-name*="island_1"] {
    transition-delay: .1s;
}
[data-name*="island_2"] {
    transition-delay: .3s;
}
[data-name*="island_3"] {
    transition-delay: .5s;
}
  • 做個開關模擬剛進入畫面的狀況
div {
	// 補間動畫 屬性 時間
	transition: all .2s;
	// 動畫,要與 @keyframe 搭配,動畫名稱 動畫時間 延遲時間 次數
	animation: animationName 2s -0.2s infinite;
	// 為了避免動畫走鐘,加上動畫時可以設定動畫的中心點,也可以寫成百分比。
	transform-orign: center center;
	
	// 滑鼠經過時觸發的內容
	&:hover { ... }
	// 行動裝置不會有 hover, 改使用為 focus
	&:focus { ... }
}

@keyframes animationName {
 // 在整段時間的 0% 要做什麼動畫
	0% { ... }
	50% { ... }
	100% { ... }
}

結語

藉由以上的操作,相信大家已經能夠利用 vue, svg 製作簡易的動畫了,下一篇老闆將帶大家逐一將場景中的動畫實現,也會與大家分享每個區塊動畫的製作思維。

課程推薦

老闆在Hahow好學校開了兩門課,其中,動畫互動網頁程式入門(HTML/CSS/JS)以簡單例子帶你入門網站的基礎架構及開發,用素材刻出簡單有趣又美觀的網頁和動畫,享受做出獨一無二的網頁所帶來的成就感,在職場上與設計師和工程師合作無間。

打好基本的互動網頁基礎之後,可以進階動畫互動網頁特效入門(JS/CANVAS),紮實掌握JavaScript 程式與動畫基礎以及進階互動,整合應用掌控資料與顯示的Vue.js前端框架,完成具有設計感的互動網站。期待在課程裡見到你!

墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

PHP Code Snippets Powered By : XYZScripts.com