#animation 彙整 | Creative Coding TW - 互動程式創作台灣站 https://creativecoding.in/tag/animation/ 蒐集互動設計案例、教學與業界資源,幫助你一起進入互動程式創作的產業 Mon, 14 Jun 2021 09:25:56 +0000 zh-TW hourly 1 https://wordpress.org/?v=6.2.2 https://creativecoding.in/wp-content/uploads/2022/03/cropped-cct-logo-icon-2-32x32.png #animation 彙整 | Creative Coding TW - 互動程式創作台灣站 https://creativecoding.in/tag/animation/ 32 32 來做SVG動畫讓蔥油餅翻滾吧! (下):讓場景中的元件動起來(直播筆記) https://creativecoding.in/2021/01/15/%e4%be%86%e5%81%9asvg%e5%8b%95%e7%95%ab%e8%ae%93%e8%94%a5%e6%b2%b9%e9%a4%85%e7%bf%bb%e6%bb%be%e5%90%a7-%ef%bc%8d%e4%b8%8b%e7%af%87%ef%bc%9a%e8%ae%93%e5%a0%b4%e6%99%af%e4%b8%ad%e7%9a%84%e5%85%83/ Fri, 15 Jan 2021 10:46:07 +0000 https://creativecoding.in/?p=469 本文翻自 [週四寫程式系列] 來做SVG動畫讓蔥油餅翻滾吧!,若是對文章內容有疑問,或是想要老闆手把手帶你飛,都可以觀看影片詳細內容。 在上一篇中,老闆帶大家從發想素材、將素材引入網頁,到製作場景進出…

這篇文章 來做SVG動畫讓蔥油餅翻滾吧! (下):讓場景中的元件動起來(直播筆記) 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>

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

在上一篇中,老闆帶大家從發想素材、將素材引入網頁,到製作場景進出的動畫。接下來我們將要賦予場景中的每個元件生命。

目標

本篇文章中,老闆會帶大家完成蔥油餅小島中角色與物件的動畫,也會提示大家每個部份需要注意的地方,以下動畫的設定數值都都只是參考,開發時大家都能試試看不同的數值。

  • 實際應用﹔讓場景中的元件動起來

讓素材動起來吧

驚嘆號

首先我們從驚嘆號下手,老闆讓驚嘆號分布在場景的各處,用意是要提示使用者這邊有驚喜,引導使用者靠近這個區塊。為了增加提示效果,我們利用左右晃動的動畫效果,固定時間後會再撥放。

這邊使用了新的 css 屬性 animation ,需要搭配 @keyframes 使用,在 keyframes 用百分比去註記不同時間該顯示的樣式,透過 animation 定義動畫總時間,這也代表這個 keyframes 可以提供給不同元件使用,使用的元件賦予不同的時間等屬性,就是一個全新的樣貌。

要注意元件會以左上角為旋轉中心點,適時加上 transform-origin, transform-box 讓動畫更加合理。

[data-name="sign"]{
	// 引用動畫名稱 時間 延遲播放時間 次數
  animation: drag 2s infinite;
  transform-origin: center center;
  transform-box: fill-box;
}

@keyframes drag {
  0%{transform: rotate(0deg);}
  80%{transform: rotate(0deg);}
  85%{transform: rotate(10deg);}
  90%{transform: rotate(-6deg);}
  95%{transform: rotate(3deg);}
  100%{transform: rotate(0deg);}
}

路人 trigger_door_man

利用前面寫過的 keyframes drag 與 data-name 的概念,我們可以快速完成這個部分的動畫。當滑鼠進入感應區塊,路人能夠開始搖擺。

[data-name="trigger_door_man"]{
	&:hover{
	  animation: drag 2s infinite;
	  transform-origin: center bottom;
	  transform-box: fill-box;
	}
}
驚嘆號與路人

阿伯與跳起來的蔥油餅 trigger_cookie

要讓蔥油餅動起來之前,先從阿伯的手開始,結合蔥油餅動畫之後,讓蔥油餅宛如真的被阿伯翻了起來。撰寫這邊的動畫時,要注意調整 transform-origin ,決定動畫旋轉的參考點,阿伯的上半身也是用相同的方式處理,若是動畫沒調好,很有可能瞬間變成凶殺案,阿伯被腰斬的畫面。

透過 animation 內延遲時間設為負值,讓動畫預先開跑到其他時間點,也是讓動畫更加順暢的小訣竅。

[data-name="trigger_cookie"]{
	&:hover {
		[data-name="man_upper"]{
			animation: bake_cookies 2s infinite ;
			transform-origin: center bottom;
  		transform-box: fill-box;
		}
		[data-name="hand"]{
			// 動畫名稱 動畫時間 次數 延遲時間
			animation: drag 2s infinite -0.8s;
			transform-origin: left center;
  		transform-box: fill-box;
		}
	}
}
@keyframes bake_cookies {
	40%{
			transform: rotate(5deg);
	}
	50%{
			transform: rotate(-6deg);
	}
	70%{
			transform: rotate(-10deg);
	}
	90%{
			transform: rotate(-6deg);
	}
	100%{
			transform: rotate(5deg);
	}
}

接著我們要來處理跳起來的蔥油餅了,蔥油餅的思維比較不同,我們要讓蔥油餅分段顯示。 keyframe 的動畫內容改為使用透明度,讓透明度跟著時間改變,營造出分段顯示的效果,利用 animation-delay 來讓四個位置的蔥油餅,在不同的時間點顯示。這邊起始為置的蔥油餅會出現大部分的時間,所以要特別為它寫一個 keyframe。大家也可以試試看,調出順暢有趣的效果。

[data-name="trigger_cookie"] {
	&:hover {
		...
		[data-name="cookie1"] {
			animation: bake_cookies_locus 2s infinite -1s;
		}
		[data-name="cookie2"] {
			animation: bake_cookies_locus 2s infinite -0.8s;
		}
		[data-name="cookie3"] {
			animation: bake_cookies_locus 2s infinite -0.6s;
		}
		[data-name="cookie4"] {
			animation: bake_cookies_locus 2s infinite -0.4s;
		}
		[data-name="now_cookie"] {
			animation: now_cookie 2s infinite;
		}
	}
}
@keyframes bake_cookies {
	40% {
		transform: rotate(5deg);
	}
	50% {
		transform: rotate(-6deg);
	}
	70% {
		transform: rotate(-10deg);
	}
	90% {
		transform: rotate(-6deg);
	}
	100% {
		transform: rotate(5deg);
	}
}
@keyframes now_cookie {
	0% {
		opacity: 1;
	}
	49% {
		opacity: 1;
	}
	50% {
		opacity: 0;
	}
	90% {
		opacity: 0;
	}
	91% {
		opacity: 1;
	}
}

小孩與媽媽 trigger_cookie

不可能整個畫面都使用同樣的搖擺動態吧?所以我們為小孩換一個動態效果,讓他原地跳躍,要達成這個效果,可以改變 y 的值來達成,媽媽則是繼續搖擺效果。

[data-name="trigger_cookie"] {
	&:hover {
		[data-name="child"] {
			animation: jump 2s infinite -1s;
		}
		[data-name="mother"] {
			animation: drag 5s infinite;
			transform-origin: left bottom;
			transform-box: fill-box;
		}
	}
}
@keyframes jump {
	0%{
		transform: translateY(0px);
	}
	50%{
		transform: translateY(0px);
	}
	51%{
		transform: translateY(0px);
	}
	75%{
		transform: translateY(-10px);
	}
	100%{
		transform: translateY(0px);
	}
}
跳動的小孩與搖擺媽媽

結語

跟著操作之後,應該有 svg + css 製作動畫的概念,這時不妨動手試試看,讓其他小島的元件動起來。也可以畫些素材,加上動畫賦予他們生命力。動畫沒有什麼對或錯,可以按照自己喜好,去改變動畫效果或是調整時間,但要注意撰寫動畫時的連續繼承問題,像是阿伯的手(子層)會跟隨著身體(父層)擺動。下面老闆也提供三個議題,供大家在開發時參考。

引用 animate.css

每次都要重新寫 keyframe,若是寫 keyframe 寫累了或是遇到急案,為了加速開發,老闆這邊準備了一些補品,讓你可以快速套用現成的動畫效果。例如:想要實現當滑鼠進入感應區塊時,讓驚嘆號動畫改為閃爍動畫,在這邊我們結合 animate.css 製作閃爍動畫。引用 ainmate.css 後,當 data-name=”trigger ” hover 時,裡面 data-name=”sign”的動畫都改為 animation: flash 2s infinite。( flash 為 animate.css 的動畫名稱)

電腦與手機

由於手機等行動裝置不會有 hover 的行為,記得補上 focus,讓整個網頁能夠更完善。

了解你的使用者

把作品完成後,如果能夠知道自己這些得意之作是不是真的有被使用,可以做 GA 追蹤,老闆也因為 GA 的關係,發現其實使用者不太常使用換頁,導致這些動畫做了卻沒人看,參考數據後做了相對應的處理,增加作品露面的機會。

課程推薦

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

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


墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

這篇文章 來做SVG動畫讓蔥油餅翻滾吧! (下):讓場景中的元件動起來(直播筆記) 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
老闆的網頁實驗室#2-實作 Canvas 遮罩動畫 https://creativecoding.in/2020/03/06/%e8%80%81%e9%97%86%e7%9a%84%e7%b6%b2%e9%a0%81%e5%af%a6%e9%a9%97%e5%ae%a42%ef%bc%8d%e5%af%a6%e4%bd%9c-canvas-%e9%81%ae%e7%bd%a9%e5%8b%95%e7%95%ab/ Thu, 05 Mar 2020 17:47:27 +0000 https://creativecoding.monoame.com/?p=95 案例解析 Louis Ansa — Portfolio 這次要分析的是在法國的設計師 Louis Ansa 的作品集網頁,在 Louis Ansa 的網頁中開始的載入與關於頁面都有出現的遮罩效果,讓老…

這篇文章 老闆的網頁實驗室#2-實作 Canvas 遮罩動畫 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>
案例解析

Louis Ansa — Portfolio

這次要分析的是在法國的設計師 Louis Ansa 的作品集網頁,在 Louis Ansa 的網頁中開始的載入與關於頁面都有出現的遮罩效果,讓老闆帶著大家來看看這是如何實現的吧!

分析思路

這一頁的動畫主要有三個部分組成:

  1. 球型遮罩:在圓形裡面的文字會呈現不同的背景色與內文顏色
  2. 移動的球體:兩個球體的圓心沿著畫面的中心做圓周運動
  3. 變動的球體形狀:球體的邊界呈現不規則波動

首先針對1.的部分,要改變特定區域內的顏色效果,依據需要達成的效果不同,我們可以直接選擇改變區域內的顏色內容;或是使用兩層圖片,再將區域內不需要的上層元素移除掉。

如果只需要處理顏色的變換,沒有非常複雜的動畫,可以使用 css 的 mix-blend-mode 屬性來實現,mix-blend-mode 提供了saturationhuedifference等條件直接處理顏色。但是考量到後續如果需要做出多個物件、比較複雜的變形以及效能問題,從 Canvas 下手就會更靈活。

實作

1. 創建兩層 canvas

首先先使用兩層的canvas,並做出完全相同的長寬、內文、行高與字體大小的圖片:


canvas.draw = function() {
  ctx = this.ctx;
  requestAnimationFrame(() => {
   this.draw(ctx);
  });
ctx.fillStyle = this.backgroundColor;
  ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
  ctx.beginPath();
  ctx.fillStyle = this.fillStyle;
  ctx.lineWidth = 5;
  ctx.font = "bold 100px Montserrat";
  // 這邊先給出一個 text 的變數是用來測量行高,以便換行書寫、定位圖形中心
  text = "Monoame";
  var textWidth = ctx.measureText(text).width;
  var textHeight = parseInt(ctx.font.match(/\d+/), 10);
  ctx.fillText("Monoame", this.cx - textWidth / 2, this.cy - textHeight / 2);
  ctx.fillText("Studio", this.cx - textWidth / 2, this.cy + textHeight / 2);
 };
底層(透過遮罩看到)的背景與文字顏色
上層的背景與文字顏色

2. 設定遮罩圖形與透視的效果

這個步驟是整個案例的核心,我們使用到 canvas 的 globalCompositeOperation屬性,globalCompositeOperation可以指定 canvas 針對當前繪製圖形與背景的交互效果。

舉例來說,預設的值是 source-over即是直接覆蓋過背景的圖層,畫上新的路徑;而我們使用到的是 destination-out,可以將新舊圖形重疊的區域設定為透明,只在沒有重疊的的部分畫出圖形。

source-over 預設值。將新圖形畫在舊圖形之上。
destination-out
只保留新、舊圖形非重疊的舊圖形區域,其餘皆變為透明。

左圖片中,藍色方形是背景的原始圖形,紅色圓形是新繪製的圖形,我們可以比較一下兩種形式對於背景圖形的影響。關於 globalCompositeOperation的更多選項與說明可以參考 MDN 的 Canvas 教學

實作中先在上層的 canvas 中繪製出作為遮罩的圓形,並在繪製圓形之前將 ctx.globalCompositeOperation設定為"destination-out",如此一來,在這個圓形的範圍內,原本被上層遮住的黑底紅字的底層就會顯示出來。最後也別忘了,在繪製完遮罩的部分之後將參數設定回原本的 "source-over",這樣第一個部分就大功告成了!

ctx.globalCompositeOperation = "destination-out";
ctx.arc(mousePos.x, mousePos.y, this.r, 0, Math.PI * 2, false);
ctx.fill();
ctx.globalCompositeOperation = "source-over";
只有在圓形區域內的上層會顯示為透明

3. 創建圍繞著圖片中心轉動的動態效果

有了圓形遮罩之後,我們要如何讓他繞著圖形的中心點做圓周運動呢?

這裡我們可以活用 canvas 的 translate 與 rotate 方法,在每一次渲染的時候,先使用rotate 將畫布旋轉 1 度,之後再使用translate移動到遮罩的圓心位置,這樣就可以創造出像是衛星環繞的圓周運動效果了。這裡有個小地方要注意,就是我們在移動圍繞的中心點跟旋轉畫布之前,要先用 ctx.save()將目前的畫布資訊存起來,等到繪製完成之後,再使用 ctx.restore() 回復到旋轉跟移動之前的位置,才不會影響到其他部分的圖形繪製喔。

在每一禎的圖片的繪製中,我們都會先旋轉畫布,再將座標移動到遮罩的圓心

ctx.clearRect(0, 0, canvas.width, canvas.height);
angle = (angle+1) % 360;

ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(2* Math.PI* angle/360);
ctx.beginPath();
ctx.arc(0, 0, dotR, 0, 2 * Math.PI, false);
ctx.fillStyle = "#000000";
ctx.closePath();
ctx.fill();

ctx.translate(100, 0);

ctx.fillStyle = "#FF0000";
ctx.beginPath();
ctx.arc(0, 0, circleR, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.fill();

ctx.restore();

旋轉的部分可以參考這個範例:

See the Pen Canvas rotate around point by Ankycheng (@ankycheng) on CodePen.

登愣,老闆上菜啦!

結合以上的步驟,最後的成品就是這樣:

See the Pen canvas mask effect by Ankycheng (@ankycheng) on CodePen.

這個案例使用遮罩加上簡單的動態實現靈活變動的效果,關於遮罩的應用還有很多,像是這個案例就使用了一樣的 canvas 特性做出類似刮刮卡的效果:https://codepen.io/dudleystorey/pen/yJQxLX。而形狀的部分,除了使用單純的圓形,我們也可以模擬原版中抖動的邊框,或是不同形狀的靈活變化。

有什麼有趣的想法都歡迎在留言告訴老闆,或是你覺得這樣的特性還有哪些可以靈活運用的地方呢?如果這篇文章超過 15 個留言的話,老闆將會進一步解密如何做出原本中華麗的動態球體!老闆的網頁實驗室,我們下回見囉!

手刀訂閱老闆來點寇汀吧!讓老闆帶你拆解更多有趣的程式案例 👨‍🍳

參考資料:

CSS: mix-blend-mode
Canvas: globalCompositeOperation

課程推薦

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

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

墨雨設計banner

訂閱 Creative Coding Taiwan 電子報:

這篇文章 老闆的網頁實驗室#2-實作 Canvas 遮罩動畫 最早出現於 Creative Coding TW - 互動程式創作台灣站

]]>