經(jīng)歷了十多篇的渲染器以及閑聊js: 實(shí)現(xiàn)一個關(guān)鍵的,最小化的亿笤,非場景圖類型的精靈系統(tǒng)(上)和閑聊js: 實(shí)現(xiàn)一個關(guān)鍵的翎迁,最小化的,非場景圖類型的精靈系統(tǒng)(下)净薛,我們已經(jīng)有了一個可以演示動畫汪榔,數(shù)學(xué),碰撞檢測的小類庫肃拜。今天是第一篇!
先看gif吧:
- 并行動畫:物體一邊放大痴腌,一邊繞x軸(pitch,上下轉(zhuǎn))旋轉(zhuǎn)燃领,一邊朝前方平移
- 達(dá)到要求的位置后士聪,緊接著繞y軸(yaw,左右轉(zhuǎn))旋轉(zhuǎn)一定角度
- 上述過程中猛蔽,物體的表面顯示繞z軸(roll剥悟,滾轉(zhuǎn))旋轉(zhuǎn)的精靈和網(wǎng)格背景
本篇目的:
通過一個css 3D 動畫 + BLFRender2D協(xié)同作戰(zhàn)的Demo,來了解
- 什么是動畫(Animation)
- 屬性動畫(Property Animation)
- 動畫按時間發(fā)生的順序進(jìn)行分類
- css3對動畫的支持
- css3和BLFRender2D的對接
- css3中 transition vs animation
- 什么是動畫:
按照opengl紅寶書對動畫的定義是: 重繪(repaint)+交換(swapBuffer)
我個人來擴(kuò)展一下對動畫的定義是: 重復(fù)的【更新(update) + 重繪(repaint) + 交換(swapBuffer)】
也就是我們BLFEngine2D中的run所做的事情
run(msec) {
//更新
this.updateAll(msec);
//重繪
this.renderAll();
//重復(fù)
//調(diào)用requestAnimationFrame
requestAnimationFrame((msec) => { this.run(msec) });
}
update中曼库,我們更新我們的位置区岗,角度,縮放凉泄,顏色躏尉,alpha,.......一切可以變化的屬性(例如ios/android中的屬性動畫)
repaint中進(jìn)行繪圖渲染,將渲染結(jié)果寫入到后備緩沖區(qū)中
swapBuffer是指渲染后后众,提交顯存顯示
這一步在瀏覽器中你看不到胀糜,因?yàn)闉g覽器(目前只要是繪圖庫,都是雙緩存蒂誉,最大的好處是避免閃爍)幫你做了這部操作教藻。實(shí)際從底層來看,就是經(jīng)典的雙緩存bitblt【閑聊js:創(chuàng)建一個演示用的渲染庫4(渲染表面右锨,像素格式括堤,光柵化,位塊傳輸,圖形與圖像)】操作悄窃。如果是全屏獨(dú)占模式(玩游戲都知道吧讥电,我也不解釋了),則僅僅是雙顯存緩沖區(qū)的指針交換轧抗,讓前緩沖變?yōu)楹缶彺娑鞯校缶彌_變?yōu)榍熬彌_,交替顯示横媚,速度超快(顯示的同時纠炮,另外一個在渲染,玩過dx/gl的同學(xué)應(yīng)該很了解這個機(jī)制)
- 屬性動畫:
在我們的的精靈系統(tǒng)中灯蝴,對精靈中的某個或某些屬性進(jìn)行更新和重繪恢口。
在css3/ios/android中都有屬性動畫概念,不了解的話穷躁,可以自己google/baidu一下
- 動畫從時間來看耕肩,可以分為連續(xù)動畫和并行動畫兩種類型:順序動畫(SequentialAnimation) / 并行動畫(ParallelAnimation)
順序動畫(SequentialAnimation): 表達(dá)的動作(Action)語義是:
先...然后...最終....(很顯然需前一個動作完成后,發(fā)出通知:我完成了,誰來繼續(xù)下面的事情呢?)并行動畫(ParallelAnimation): 表的的動作(Action)語義是:
一邊.....一邊....(例如:物體一邊擴(kuò)大折砸,一邊旋轉(zhuǎn)看疗,一邊平移)
- css3中對動畫的支持:
- 2d 仿射變換【閑聊js:創(chuàng)建一個演示用的渲染庫10(坐標(biāo)軸繪制、空間變換及總結(jié)與展望)】
http://www.w3school.com.cn/css3/css3_2dtransform.asp - 3d 仿射變換
http://www.w3school.com.cn/css3/css3_3dtransform.asp - 過渡
http://www.w3school.com.cn/css3/css3_transition.asp - 動畫
http://www.w3school.com.cn/css3/css3_animation.asp
關(guān)于css3方面的內(nèi)容睦授,請自行參考上述文檔。本篇不做詳解
- css3和BLFRender2D的對接(css3代碼來自與apple公司的flipcard demo,修改后用于我的demo)
- 為了減少對jquery的依賴摔寨,對Html Element元素進(jìn)行擴(kuò)展去枷,定義最小化的css class類似操作(http://api.jquery.com/category/attributes/)
這些操作比較通用,就定義在BLFES6Lib.js中吧是复!
//為了防止和jquery名字發(fā)生沖突删顶,增加name后綴
//例如jquery中是addClass,這里就變成了addClassName
Element.prototype.hasClassName = function (a) {
return new RegExp("(?:^|\\s+)" + a + "(?:\\s+|$)").test(this.className);
};
Element.prototype.addClassName = function (a) {
if (!this.hasClassName(a)) {
this.className = [this.className, a].join(" ");
}
};
Element.prototype.removeClassName = function (b) {
if (this.hasClassName(b)) {
var a = this.className;
this.className = a.replace(new RegExp("(?:^|\\s+)" + b + "(?:\\s+|$)", "g"), " ");
}
};
Element.prototype.toggleClassName = function (a) {
this[this.hasClassName(a) ? "removeClassName" : "addClassName"](a);
};
//上面代碼都很簡單,下面這個是加強(qiáng)版的函數(shù)
Element.prototype.changeClassName = function(remove,add) {
if(this.hasClassName(remove))
this.removeClassName(remove);
if(add)
this.addClassName(add);
}
- 需求描述:
- 并行動畫:物體一邊放大淑廊,一邊繞x軸(pitch逗余,上下轉(zhuǎn))旋轉(zhuǎn),一邊朝前方平移
- 達(dá)到要求的位置后季惩,緊接著繞y軸(yaw录粱,左右轉(zhuǎn))旋轉(zhuǎn)一定角度
- 上述過程中,物體的表面顯示繞z軸(roll画拾,滾轉(zhuǎn))旋轉(zhuǎn)的精靈和網(wǎng)格背景
- yaw/pitch/roll【歐拉角】來源于飛行器的姿態(tài)描述啥繁,在3D中用于描述物體的朝向,先暫時了解一下吧青抛。其實(shí)很多基礎(chǔ)知識旗闽,專業(yè)術(shù)語要了解,然后才能更精確的google/baidu,否則范圍太廣适室,搜索不到
- css3動畫:
.container {
width: 600px;
height: 400x;
margin: 0 auto 40px;
border: 2px solid red;
perspective: 1200px;
/* 設(shè)置3D投影矩陣*/
}
@keyframes myTransform {
from {
transform: translate3d(0px, 0px, -5000px) rotateX(-720deg);
/*從-720度*/
}
to {
transform: translate3d(0px, 0px, 0px) rotateX(720deg);
/*到720度*/
}
}
@keyframes myYrotate {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(720deg);
}
}
/*并行動畫*/
.animation {
width: 100%;
height: 100%;
transform-style: preserve-3d;
/*使用3d變換*/
animation: myTransform 5s;
}
/*順序動畫第二步*/
.animation1 {
width: 100%;
height: 100%;
transform-style: preserve-3d;
/*使用3d變換*/
animation: myYrotate 5s;
}
- html層次樹及css3使用如下:
<body>
<h1>隨風(fēng)而行之青衫磊落險峰行 BLFRender2D + CSSAnimation3D Demo</h1>
<section class="container">
<canvas id="myCanvas" class="animation" width="600" height="400">
你的瀏覽器還不支持哦
</canvas>
</section>
</body>
- js控制代碼:
var init = function() {
let animationDiv = document.getElementById("myCanvas");
//初始化時候嫡意,canvas上的動畫使用的是上下旋轉(zhuǎn)及向前平移(典型的并行動畫),一旦完成后
//觸發(fā)webkitAnimationEnd事件
//對webkitAnimationEnd事件進(jìn)行處理捣辆,切換css為左右旋轉(zhuǎn),很典型的順序動畫
//當(dāng)完成一個動畫序列后鹅很,瀏覽器會發(fā)送一個完成事件
//我們對該事件進(jìn)行處理就可以了animationDiv.addEventListener("webkitAnimationEnd", function() {
animationDiv.changeClassName("animation", "animation1");
}, false);
};
//掛接init事件處理函數(shù)
window.addEventListener('DOMContentLoaded', init, false);
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext('2d');
let engine = new BLFEngine2D(context);
let spr2 = new BLFDemoSprite(true);
spr2.y = 200;
spr2.rotateSpeed = -1; //逆時針
engine.sprMgr.addSprite(new BLFGridSprite("background"));
engine.sprMgr.addSprite(spr2);
engine.run(); //run的是BLFSprite精靈系統(tǒng)的動畫
運(yùn)行一下看效果:http://htmlpreview.github.io/?https://github.com/jackyblf/BLF_JS_Demos/blob/master/css3withBLFRender2D.html
可能看不到效果,我也不知道為什么,也懶得花時間解決了
大家可以到我的github上下載代碼
如果感覺不錯罪帖,給我的github加顆小星星促煮,鼓勵鼓勵我!
對了整袁,在使用css3中的animation/transition中遇到一些問題菠齿,然后查了一些資料結(jié)合實(shí)踐,總結(jié)一下一起分享吧:
- transition簡單易用坐昙,但是有如下幾個缺點(diǎn):
- 沒法自動運(yùn)行(init中),只能靠事件觸發(fā)(例如click)
- 無法循環(huán)運(yùn)行绳匀,只能一次結(jié)束
- 只能設(shè)置開始,結(jié)束狀態(tài)炸客,無中間任意多的過度狀態(tài)設(shè)置
- 只能animate一個屬性疾棵,例如設(shè)置了移動就不能旋轉(zhuǎn)
綜上所述,transition全部的缺點(diǎn)就是animation的優(yōu)點(diǎn)痹仙!