有時候會碰到網站要放GIF動畫
,但GIF大小動輒幾M起跳,
造成網頁Loading慢、圖片邊緣鋸齒,支援顏色也不多,不太完美。
這時候 sprite 雪碧圖
就登場啦~
其實雪碧圖就是將動畫拆解成一張一張圖片,
再用CSS animation steps的做法(就跟之前換字特效是一樣的!)
讓他可以一張一張播放。
當然雪碧圖也可以用在組合多張圖片,讓網路只要載入一次,
不過這個應用就不會在這邊贅述囉~(我也還不太會)
今天就來用
1.CSS Animation
2.Canvas + JS
兩種方法來做sprite動畫!
當然這邊就要 設計師請支援動畫
但我一個人兼撞鐘,眼睛就忍耐一下!
很粗糙地先做了五個連續圖片~讓雲和燈光可以動起來。
直覺可能會想到要一張圖片一張圖片換,
但這樣做會造成缺點:多個HTTPS的請求
、會造成檔案閃爍
、不利於管理
等等。
雪碧圖搭配移動圖片位置
的方法換圖片,
只要一張圖片搞定啦!
來看成品:
直接上code:
//css
.hero {
width: 648px;
height: 572px;
background: url(./city-sprite.png);
background-size: auto 100%;
animation: bg steps(4) 5s infinite;//移動4次
}
@keyframes bg {
to {
background-position: -2592px 0; //算好移動到最後一張的寬度
}
}
Canvas的話,就是不斷擦掉畫面,
再requestAnimationFrame(animate);
不斷呼叫自己重繪圖片到Canvas上~
上圖片~
我們一樣要算出每格的距離,然後讓Canvs去吃那格的座標~
來看看成果~
直接看code說明吧~
//JS
//canvas 起手式
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 600;
canvas.height = 600;
//canvas 放圖片起手式
const spriteSheet = new Image();
spriteSheet.src="./test.png";
//異步操作,讓圖片載入後才執行
spriteSheet.onload = loadImage;
//spriteSheet的寬高除以圖片有幾格,就是一格的寬度和高度
//這裡有五格,但只有一行
let cols = 5;
let rows = 1;
let spriteWidth = 1147 / cols; //圖片寬度除格數
let spriteHeight = 557 / rows; //圖片高度除格數
//圖片切割的起始點
let srcX =0;
let srcY =0;
//這邊是控制速度用的~
let totalFrames = 5;
let currentFrame = 0;
let frameDrawn =0;
function animate(){
//先清掉畫布
ctx.clearRect(0,0,canvas.width, canvas.height);
//這邊用於數的概念來看現在是第幾格了~等到第五格上限時,currentFrame又回從一開始~
currentFrame = currentFrame % totalFrames;
//現在這個是第幾格
srcX = currentFrame * spriteWidth;
//畫畫囉參數分別是:1. 讀取圖片 2.圖片要切割的x位置 3.切割的y位置
//4.切割多寬 5.切割多長 6.要放在canvas的x位置 7.要放在canvas的y位置
//8.canvas貼上的地方要放多寬 9.canvas貼上的地方要要放多長
ctx.drawImage(spriteSheet, srcX, srcY,spriteWidth, spriteHeight,
0,0 ,spriteWidth, spriteHeight);
//就是這邊控制速度
//等於是這個animate被呼叫10次以後,currentFrame才會前進一格,以控制速度
frameDrawn++;
if(frameDrawn>=10){
currentFrame++;
frameDrawn=0;
}
//重複呼叫自己
requestAnimationFrame(animate);
}
function loadImage(){
animate();
}
// ref: https://www.youtube.com/watch?v=MHGgVlrlkYc&t=907s
成果看這邊
完成了我們的小人物動畫囉!
明天就來利用這個小人物來做互動小遊戲~(命名:都市老妹生存記)
敬請期待 XD
Canvas的sprite我主要是參考這個影片
有錯或是有任何建議歡迎批評指教!
參考文章
幀動畫的多種實現方式與效能對比(推薦閱讀!)
https://www.gushiciku.cn/pl/2RQ8/zh-tw
CSS3动画之逐帧动画
https://jelly.jd.com/article/6006b1035b6c6a01506c87a7