覽器和 JavaScript 的功能逐年不斷的變強(qiáng)變大。曾幾何時(shí),任何類型的游戲都需要Flash。但隨著 HTML5 發(fā)展,HTML5 + WebGL 游戲式就慢慢占領(lǐng)著這個(gè)舞臺(tái)。以下是30款流行的游戲,它們可以在所有現(xiàn)代瀏覽器中運(yùn)行,并且只使用web技術(shù)構(gòu)建。
地址:http://hexgl.bkcore.com/
類型:街機(jī),賽車
HexGL 是一款基于HTML5,JavaScript和WebGL的快節(jié)奏的賽車游戲。玩家可以使用鍵盤,觸摸屏設(shè)備或leap motion(體感控制器)來(lái)控制太空飛船。
地址:http://www.cross-code.com/en/home
類型:動(dòng)作,角色扮演
一個(gè)復(fù)古靈感的2D游戲設(shè)定在遙遠(yuǎn)的未來(lái)。這是一個(gè)充滿偉大的游戲機(jī)制,如組合,拼圖,技能樹,任務(wù),物品等等。
地址:https://sketch-out.appspot.com/
類型:街機(jī)
Sketchout的任務(wù)保護(hù)你的行星,并通過(guò)改變流星的方向來(lái)消滅對(duì)手,通過(guò)使流星偏轉(zhuǎn)來(lái)保護(hù)您的星球并消滅對(duì)方,這款游戲有很棒的視覺效果和音樂特效。
地址:http://www.treasurearena.com/類型:多人,角色扮演,動(dòng)作
Treasure Arena 是一款動(dòng)態(tài)的競(jìng)技場(chǎng)戰(zhàn)斗游戲,最多可容納4名玩家。它具有不同的游戲模式,出色的幀率和配樂,是一個(gè)非常有趣的游戲。
地址:http://bejeweled.popcap.com/html5/
類型:街機(jī),解謎,娛樂
HTML5格式的經(jīng)典“寶石迷陣”游戲。這是一個(gè)官方克隆,因此可以正常運(yùn)行且外觀完美。
地址:http://missile-game.bwhmather.com/類型:街機(jī)
這是一款非常具有挑戰(zhàn)性的游戲,游戲中我們扮演的是一枚被發(fā)射進(jìn)隧道的導(dǎo)彈。游戲有很酷的黑白圖像,玩的時(shí)候會(huì)有很強(qiáng)的場(chǎng)景效果。
地址:http://www.deconstructeam.com/games/gods-will-be-watching/類型:拼圖
在這個(gè)令人毛骨悚然(但又很棒)的游戲中,我和自己團(tuán)隊(duì)必須獨(dú)自生存40天。團(tuán)隊(duì)有六名成員,其中包括一只狗,一名精神病醫(yī)生和一個(gè)機(jī)器人,您必須與他們互動(dòng),以使其保持溫暖,溫飽和理智的狀態(tài)。
地址:http://www.sinuousgame.com/類型:街機(jī)
一個(gè)簡(jiǎn)單的游戲,極簡(jiǎn)的圖形和流暢的幀率。拾取電源時(shí)避免與紅點(diǎn)碰撞。此外,如果你想要那些額外的積分,就需要不停向前移動(dòng)
地址:http://swooop.playcanvas.com/類型:街機(jī)
在一個(gè)美麗多彩的3D世界里,到處飛翔,收集寶石和星星。
地址:http://www.freeriderhd.com/
Free Rider HD 是一款令人上癮的游戲,你可以在其他玩家繪制的賽道上騎自行車。可以在成千上萬(wàn)的播放器曲目中選擇一個(gè)播放,也可以創(chuàng)建自己的曲目并分享。
地址:http://entanglement.gopherwoodstudios.com/zh-CN-index.html類型:拼圖,娛樂
這個(gè)游戲的目的是通過(guò)在網(wǎng)格上放置線段來(lái)創(chuàng)建一條盡可能長(zhǎng)的路徑。你可以單獨(dú)玩,也可以和朋友一起玩。
地址:https://www.modern.ie/en-us/ie6countdown#escape-from-xp
類型:動(dòng)作,街機(jī)
用“Escape from XP”來(lái)慶祝 Windows XP 的終結(jié)。你的任務(wù)是拯救最后一個(gè)陷入Clippy暴政的開發(fā)人員。
地址:http://polycraftgame.com/類型:角色扮演,塔防,動(dòng)作
在這個(gè)很棒的3D游戲中,你到處收集資源,建造東西,完成任務(wù)。關(guān)于它的所有東西都經(jīng)過(guò)拋光,并且運(yùn)行也非常順暢。
地址:https://gabrielecirulli.github.io/2048/類型:拼圖
一個(gè)非常上癮的游戲,你可能已經(jīng)玩過(guò)了。在 2048 ,你移動(dòng)編號(hào)的圖塊并合并它們。當(dāng)界面中最大數(shù)字是`2048 時(shí),游戲勝利。
地址:http://arcade.lostdecadegames.com/onslaught_arena/
類型:動(dòng)作
一種快節(jié)奏的復(fù)古生存游戲,您可以使用不同的武器與成群的敵人作戰(zhàn)。
地址:http://chrome.angrybirds.com/類型:游戲
《憤怒的小鳥》游戲,這就不用介紹了。
地址:https://www.cubeslam.com/mcycrs
類型:街機(jī),多人
具有豐富的色彩和炫酷的3D圖形乒乓球游戲。我們可以通過(guò)向朋友發(fā)送一個(gè)URL來(lái)挑戰(zhàn)他們,還可以通過(guò)網(wǎng)絡(luò)攝像頭看到對(duì)方。
地址:http://hypnoticowl.com/games/the-wizard/類型:動(dòng)作,角色扮演,策略
Wizard 是基于回合的地牢爬行者,在里面會(huì)遇到神話般的怪物并找到奇妙的咒語(yǔ)。該游戲具有酷炫的戰(zhàn)斗機(jī)制,有時(shí)可能會(huì)帶來(lái)很大挑戰(zhàn)。
地址:http://phoboslab.org/xtype/類型:動(dòng)作,街機(jī)
在這款酷炫的太空射擊游戲中,你目的就是要起戰(zhàn)勝 Boss。
地址:http://orteil.dashnet.org/cookieclicker/類型:休閑,搞笑
Cookie clicker 是一款可能為了開玩笑而創(chuàng)建的游戲,但仍然提供了大量的樂趣。你可以從0個(gè)cookie開始,然后單擊一些有效率的cookie,最后你可能會(huì)發(fā)現(xiàn)自己擁有數(shù)十億個(gè)cookie。
地址:http://play.elevatorsaga.com/類型:拼圖,編碼
這類屬于程序員類型游戲 。在電梯中的任務(wù)是通過(guò)對(duì)電梯的運(yùn)動(dòng)進(jìn)行編程,以最有效的方式運(yùn)送人員,這些都是用 JavaScript 來(lái)完成的。
地址:http://gameofbombs.com/landing類型:動(dòng)作,角色扮演,多人
Game of Bombs是一個(gè)轟炸機(jī)類型的游戲,在廣闊地圖上,都有著敵方玩家。收集力量,皮膚和成就,以成為最佳轟炸機(jī)玩家的方式。
地址:http://or.paleozoic.com/類型:平臺(tái)游戲,動(dòng)作
Olympia Rising具有漂亮復(fù)古外觀圖形的游戲。它坐落在古希臘,在那里我們扮演的女人被賦予了重新的機(jī)會(huì),所以我們的任務(wù)就是逃離死者的世界。
地址: https://ned.im/pixel-race-game/類型:街機(jī),賽車
Pixel Race是一款簡(jiǎn)單概念概念,你可以在收集硬幣的同時(shí)控制汽車以避開障礙物。如果有足夠的耐心和空閑時(shí)間,那么你可能會(huì)打破記錄(記錄為36309個(gè)硬幣)。
地址:https://littlealchemy.com/類型:拼圖
從這四個(gè)基本元素開始,將它們組合起來(lái),創(chuàng)建510種可能的組合。
地址:http://www.kevs3d.co.uk/dev/arena5/類型:街機(jī)
在數(shù)字領(lǐng)域中飛行并射擊幾何敵人以獲得高分。
地址:https://vector-runner-remix.tresensa.com/
類型:街機(jī)
在這個(gè)充滿色彩和幾何形狀的平臺(tái)游戲中,盡你所能奔跑吧。
地址:http://playbiolab.com/類型:動(dòng)作
一款出色的像素藝術(shù)平臺(tái)游戲,你必須在這里逃脫充滿突變生物和其他不良生物的實(shí)驗(yàn)室。
地址:http://worldsbiggestpacman.com/#類型:街機(jī)
地址:http://games.jessefreeman.com/new-super-resident-raver/
從即將到來(lái)的僵尸入侵中拯救驚慌失措的人們。收集錢,升級(jí)你的武器和戰(zhàn)斗僵尸。
作者:Danny Markov 來(lái)源:tutorialzin 譯者:前端小智
原文:https://tutorialzine.com/2015/02/30-amazing-games-made-only-with-html5
言
25年過(guò)去了,Brooks博士著名的“沒有銀彈”的論斷依舊沒有被打破。HTML5也是一樣。但這并不妨礙HTML5是一個(gè)越來(lái)越有威力的“炸蛋”:發(fā)展迅速、勢(shì)不可擋。隨著HTML5技術(shù)的普及,用HTML5做可視化呈現(xiàn)的項(xiàng)目越來(lái)越多了。HTML5的優(yōu)勢(shì)明顯:網(wǎng)頁(yè)上直接運(yùn)行無(wú)需插件、手機(jī)平板方便兼容、代碼開發(fā)和維護(hù)相對(duì)容易,等等。一大波一大波的做Java、.NET甚至C++桌面的程序老手們都紛紛開始研究javascript了,而初出茅廬的新一代程序猿更是義無(wú)反顧的直奔HTML5這個(gè)技術(shù)大熱點(diǎn)而來(lái)。
HTML5涵蓋的技術(shù)點(diǎn)很多,甚至延伸到了前端、后端、通訊等各個(gè)層面。前端的canvas繪圖這塊無(wú)疑是它的核心內(nèi)容。Canvas的API雖然不是很復(fù)雜很強(qiáng)大,但是做一般的2d繪圖基本都?jí)蛴昧恕;谶@些API,一大堆的2d繪圖組件紛紛出爐。Echarts、d3.js都是很不錯(cuò)的項(xiàng)目。 Echarts主要是chart組件,而d3相對(duì)雜一些,很多呈現(xiàn)方式很有創(chuàng)意,值得研究。
概述
研究d3的起因是最近有一個(gè)項(xiàng)目,用戶截了一張效果圖讓我們用HTML5做一下:
看著很眼熟,搜了一下,感覺就是d3例子中的sunburst效果,程序在這里:
http://bl.ocks.org/mbostock/4063423
看上去似乎也不難,就是一圈一圈的餅圖,把樹狀結(jié)構(gòu)數(shù)據(jù)按占比一層一層繪制上去就行了。所以引起了自己動(dòng)手做一個(gè)的興趣?!皊unburst”英文里應(yīng)該是“云開日出”的意思,類似強(qiáng)烈的光芒從云層背后透射出來(lái),不知為何中文里大多把它翻譯成“日落”。比如這把Fender Telecaster吉他型號(hào)是Brown Sunburst款,就會(huì)被大家翻譯成“日落色”。
關(guān)于日出和日落更喜歡哪一個(gè)的問(wèn)題,網(wǎng)上還真有這樣的調(diào)查。有意思的是,選擇喜歡日落的遠(yuǎn)多于選擇日出的。日出代表希望,日落代表成熟,都是一種美,哪個(gè)更美要看你個(gè)人的心境,因?yàn)樗拿利愂怯尚纳?。為了不在這個(gè)問(wèn)題上站錯(cuò)對(duì),我們還是給他重新起一個(gè)更加響亮霸氣的中文名字:“彩虹爆炸圖”,怎么樣?
仔細(xì)研究一下彩虹爆炸圖的結(jié)構(gòu),無(wú)非就是一個(gè)樹形結(jié)構(gòu),并采用發(fā)射狀的布局。根節(jié)點(diǎn)在中間(也可以認(rèn)為沒有唯一的根,而是一堆根節(jié)點(diǎn)圍繞在第一圈),一次向外發(fā)散排列。每一個(gè)節(jié)點(diǎn)有名稱、數(shù)值。節(jié)點(diǎn)可以按照自身數(shù)值在扇區(qū)所占比例進(jìn)行繪制,這樣就不用管節(jié)點(diǎn)具體數(shù)值有多大多小了。
這種圖最先是由布朗大學(xué)教授John T. Stasko設(shè)計(jì)。
http://www.cc.gatech.edu/~john.stasko/
經(jīng)過(guò)一天的折騰,終于做出了一個(gè)還算過(guò)得去的“彩虹爆炸圖”。先上個(gè)圖看看:
主要功能包括了:
可以通過(guò)json來(lái)定義數(shù)據(jù)和樣式(類似百度的echarts那樣);
顏色可以固定,也可以自動(dòng)彩虹色;
自動(dòng)計(jì)算數(shù)值及角度占比;
動(dòng)態(tài)顯示導(dǎo)航路徑;
鼠標(biāo)動(dòng)態(tài)高亮顯示路徑;
動(dòng)畫飛入、展開導(dǎo)航路徑;
文字顯示及角度控制;
全矢量,可鼠標(biāo)縮放、平移,不失真;
下面重點(diǎn)碼一下折騰過(guò)程中的幾個(gè)重點(diǎn):
一、定義節(jié)點(diǎn)對(duì)象
首先定義每一個(gè)小扇片節(jié)點(diǎn)。每個(gè)扇片可以用一段餅圖來(lái)繪制。為了簡(jiǎn)單方便,這里用了最簡(jiǎn)單高效偷懶的方法:用一個(gè)半徑很粗的線畫一段角度的arc,即可。如下圖:
另外還有文字等內(nèi)容。所以定義它的json結(jié)構(gòu)大概如下:
var item={name: '名稱', color: 'red', angle: '45', …};
此外,下一圈的數(shù)據(jù),可直接定義為這個(gè)節(jié)點(diǎn)的“孩子節(jié)點(diǎn)”,直接在item中定義一個(gè)data的子節(jié)點(diǎn)數(shù)據(jù):
var item={name: '名稱', color: 'red', angle: '45', data:[
{name:’孩子一’, color:’green’,…},
{name:’孩子二’, color:’yellow’,…},
]};
這樣就可以組成一個(gè)樹狀結(jié)構(gòu)。接下來(lái)要在canvas上繪制圖形了。為了方便,這里直接使用了矢量圖進(jìn)行定義:
twaver.Util.registerImage('node', {
v: [{
shape: 'circle',
r: ...
lineColor: function(data,view){return data.getClient("lineColor");},
lineWidth: ...
startAngle: ...
endAngle: ...
},{
shape: 'text',
textBaseline: 'middle',
textAlign: ...
text: ...
x: ...
y: ...
font: ...
fill: ...
rotate: ...
visible: ...
shadow: ...
}],
});
矢量圖中定義了2個(gè)圖形元素:一個(gè)arc弧線、一個(gè)文字對(duì)象,分別用于畫node和繪制其文字。顏色、字體、是否可見、陰影、對(duì)齊、位置、線寬、角度…等等均在上面的定義中用一個(gè)function動(dòng)態(tài)獲取。例如,這個(gè)節(jié)點(diǎn)的半徑,通過(guò)下面的方法,就可以在圖形的lineColor屬性中保存并驅(qū)動(dòng),需要修改,直接修改lineColor這個(gè)client屬性即可,而不用去修改繪圖參數(shù),非常方便:
r:function(data,view){return data.getClient("lineColor");}
這里有一個(gè)比較啰嗦的地方是:每個(gè)扇片的角度需要根據(jù)每個(gè)item定義的原始值進(jìn)行計(jì)算角度占比。而且,對(duì)于太小的扇片,可以給一定的最小值(例如 1度),保證能視覺上看到它。否則,顯示10000和1兩個(gè)數(shù)值,由于對(duì)比過(guò)大,可能就杯具了,因?yàn)?連1度都占不到,顯示效果會(huì)非常差。還有,每個(gè)扇片之間應(yīng)該盡量留有一定的空隙。如果連續(xù)繪制,就會(huì)連成一片,沒有“分片”感。這些可以在代碼中進(jìn)行簡(jiǎn)單控制。
二、文字控制
文字控制也比較啰嗦。首先是對(duì)齊方式。最簡(jiǎn)單的方式當(dāng)然是讓文字在所在扇片處,直接居中、旋轉(zhuǎn)。這樣文字會(huì)在徑向的中間位置,如下圖:
但這樣顯示感覺并不是很完美。對(duì)于中文來(lái)說(shuō),如果能統(tǒng)一靠近圓心方向的位置對(duì)齊,會(huì)更好看一些。這樣,即使文字過(guò)長(zhǎng),也會(huì)向外延伸,不會(huì)和里面的重疊。如下圖:
還有,當(dāng)文字在左半圓時(shí),如果不做特殊處理,文字旋轉(zhuǎn)會(huì)導(dǎo)致文字大頭朝下,閱讀起來(lái)有把脖子歪斷的風(fēng)險(xiǎn)。所以應(yīng)該動(dòng)態(tài)判斷,如果文字在左側(cè),應(yīng)該文字再增加旋轉(zhuǎn)180度。同時(shí)左側(cè)的文字對(duì)齊也要特殊考慮,應(yīng)該變成右對(duì)齊,才能保持徑向的整齊一致。
文字還有一個(gè)細(xì)節(jié)就是顏色和陰影的問(wèn)題。不使用陰影,單純的使用顏色(例如白色),則在一些方向上的節(jié)點(diǎn)的文字會(huì)看不清楚,因?yàn)槲覀冏龅氖遣屎绫▓D,各個(gè)方向顏色都不一樣,而且還會(huì)隨著圈數(shù)增加而變淡顏色,所以幾乎不可能用一個(gè)固定的顏色(例如白色或黑色)能保證文字在所有地方都能和node顏色搭配并看清楚。所以思來(lái)想去還是使用了陰影效果。
聯(lián)想了一下我們看美劇時(shí)候的字幕,似乎也是同樣的問(wèn)題。視頻字幕要顯示在千變?nèi)f化的視頻場(chǎng)景里面,視頻場(chǎng)景的顏色完全隨機(jī)出現(xiàn)無(wú)從知曉,要想讓字幕看清楚,必然也會(huì)想一些辦法解決。我們仔細(xì)觀察一下視頻字幕:
仔細(xì)觀察,字幕是白色文字加了一圈黑色外框,這樣就不怕任何場(chǎng)景了。我們?cè)谖淖侄x時(shí)也模擬一下,設(shè)置陰影和陰影偏移試一試:
fill:'white',
shadow: {
offsetX: 2,
offsetY: 2,
blur: 4,
color: 'black',
},
看一下使用前和使用后的效果對(duì)比:
使用陰影后不但文字更清晰了,而且也增加了立體感,效果還是不錯(cuò)的。下面圖顯示在應(yīng)用在節(jié)點(diǎn)上的效果:
可見不論什么顏色,都能比較好的勾勒出文字輪廓,保持清晰可讀。
三、生成彩虹顏色
關(guān)于顏色,是一個(gè)有趣的話題。對(duì)于廣大程序猿來(lái)說(shuō),顏色是一個(gè)既簡(jiǎn)單又困難的東西。我們隨手就能寫下’red’, ‘green’, ‘orange’, ‘yellow’這樣的色彩斑斕的顏色,還能保證沒有語(yǔ)法錯(cuò)誤;我們還會(huì)寫’#FF55AA’、’#0c0’、’RGB(0,204,0)’、’ RGB(0%,80%,0%)’這樣的各種顏色寫法;我們也明白R(shí)GBA的含義和用途。但是,我們很少能把一個(gè)demo寫的顏色很好看、很搭配。關(guān)于顏色和配色以后再專門討論。這里我們只想自動(dòng)生成一圈彩虹一樣的顏色。用我們熟悉的RGB方法好像比較困難了。于是想起了那個(gè)HSV的顏色定義方法,它貌似很適合解決這個(gè)問(wèn)題。
HSV顏色模型定義了色調(diào)H、飽和度S和亮度V,由A. R. Smith在1978年創(chuàng)建的一種顏色空間。其中H用一圈360度表示所有顏色,從紅色開始按逆時(shí)針方向計(jì)算,紅色為0度。飽和度S從0到1,越大越飽和。亮度V從0到255(也可以轉(zhuǎn)換為從0到1,方便使用),越大越明亮,越小越暗淡。
Js里面并沒有直接處理HSV顏色的函數(shù)。不過(guò)用下面的代碼很方便可以從hsv轉(zhuǎn)為rgb:
寫一個(gè)對(duì)應(yīng)的js函數(shù)也很簡(jiǎn)單:
/* h, s, v (0 ~ 1) */
function getHSVColor(h, s, v) {
var r, g, b, i, f, p, q, t;
if (h && s===undefined && v===undefined) {
s=h.s, v=h.v, h=h.h;
}
i=Math.floor(h * 6);
f=h * 6 - i;
p=v * (1 - s);
q=v * (1 - f * s);
t=v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r=v, g=t, b=p; break;
case 1: r=q, g=v, b=p; break;
case 2: r=p, g=v, b=t; break;
case 3: r=p, g=q, b=v; break;
case 4: r=t, g=p, b=v; break;
case 5: r=v, g=p, b=q; break;
}
var rgb='#'+toHex(r * 255)+toHex(g * 255)+toHex(b * 255);
return rgb;
}
再回到我們的彩虹爆炸圖。每一個(gè)節(jié)點(diǎn)對(duì)應(yīng)的所在角度(中心角度)決定了它自己的顏色值。所以,我們可以直接根據(jù)這個(gè)角度得到顏色的h。然后,為了讓彩虹逐漸一圈一圈變淡,再把s飽和度從1逐圈遞減(例如0.1),產(chǎn)生變淡的效果。為了防止圈太多最后看不清,減到0.2到0.3左右可以停止遞減。
var fromAngle=node.getClient(‘fromAngle’);
var toAngle=node.getClient(‘toAngle’);
var level=node.getClient(‘level’);//節(jié)點(diǎn)在第幾圈
var h=(fromAngle+to)/2 % 360 /360; //中心角度,并轉(zhuǎn)換為弧度
var s=Math.max(0.2, 1-level*0.1);//每圈s遞減0.1,直到0.2為止
var v=1;
var color=getHSVColor(h, s, v);
這樣就獲得了一圈顏色。實(shí)驗(yàn)效果如下:
如果相對(duì)某個(gè)節(jié)點(diǎn)的顏色做特殊處理,例如強(qiáng)制為橙色來(lái)凸顯,我們可以在數(shù)據(jù)中定義時(shí)加個(gè)標(biāo)記,設(shè)置顏色時(shí)候直接使用而不用計(jì)算即可。
{name:'浦東新區(qū)', value: 2600, color: '#FE9A2E'}
接下來(lái)要實(shí)現(xiàn)鼠標(biāo)劃過(guò)節(jié)點(diǎn),自動(dòng)計(jì)算路徑、高亮路徑節(jié)點(diǎn)、暗淡非路徑節(jié)點(diǎn)。為了方便路徑尋找,程序把每個(gè)節(jié)點(diǎn)的下一圈子數(shù)據(jù)定義為子節(jié)點(diǎn),子節(jié)點(diǎn)通過(guò)getParent函數(shù)可以直接獲得父對(duì)象。這樣,通過(guò)不斷getParent就可以獲得整個(gè)路徑上的節(jié)點(diǎn),并修改其顏色為預(yù)設(shè)顏色,實(shí)現(xiàn)高亮效果:
var node=highlightedNode;
while(node){
node.setClient(‘color’, node.getClient(‘color.original’));
node=node.getParent;
}
對(duì)于非路徑節(jié)點(diǎn)的顏色,可以設(shè)置為預(yù)設(shè)顏色但飽和度為0.1的淡顏色 ,讓它變淡,以便突出高亮路徑:
var color=getHSVColor(h, 0.1, v);
node.setClient(‘color’, color);
四、動(dòng)畫效果
最后,為了圖形更生動(dòng),使用了一些動(dòng)畫效果。首先想到的就是圖形出來(lái)時(shí)候,用動(dòng)畫從小到大發(fā)散開來(lái),會(huì)很動(dòng)感。這樣做需要用動(dòng)畫函數(shù)來(lái)驅(qū)動(dòng)每一個(gè)節(jié)點(diǎn)的半徑位置,從0增加到所在的半徑位置,如果大家一起設(shè)置,整個(gè)圖就會(huì)動(dòng)起來(lái)。這里用了一個(gè)動(dòng)畫函數(shù)來(lái)驅(qū)動(dòng),并使用了網(wǎng)上常用的easing函數(shù)來(lái)控制,避免線性的動(dòng)畫太死板:
new Animate({
from: 0,
to: 1,
dur: 3000+level*100,
easing: 'elasticOut',
onUpdate: function (value) {
node.setLocation('pie.location’, value);
},
}).play;
上面定義的動(dòng)畫,用3秒鐘跑完,用'elasticOut'的easing方式。每一幀,修改node的位置信息。這樣就完成了橡皮筋一樣的環(huán)形彈出散開效果。
另外,導(dǎo)航條的出來(lái)也比較突兀,這里也使用一下動(dòng)畫,讓它從左到右慢慢伸出:
new Animate({
from: {x:x1, y:y1},
to: {x:x2, y:y2},
delay:50,
type: 'point',
dur: 1000,
easing: 'bounceOut',
onUpdate: function (value) {
node.setCenterLocation(value.x, value.y);
和上一個(gè)動(dòng)畫的不同之處在于這里使用了{(lán)x、y}的point結(jié)構(gòu),每一幀直接更新節(jié)點(diǎn)位置。同時(shí)設(shè)置了50毫秒的delay,讓動(dòng)畫有一點(diǎn)點(diǎn)粘性停滯,不至于太突兀。效果不錯(cuò)。
至此,彩虹爆炸圖基本上就做的差不多了。使用起來(lái)也很簡(jiǎn)單,只要準(zhǔn)備一些json數(shù)據(jù)就可以了,下面是一些有趣的數(shù)據(jù)做出來(lái)的效果。感興趣的同學(xué)可以到這里索取代碼。
實(shí)際應(yīng)用在項(xiàng)目中的示意圖。如果你也希望項(xiàng)目中用一下彩虹爆炸圖,歡迎給我發(fā)郵件索取:info@servasoft.com
掃推薦微信:中國(guó)大數(shù)據(jù)
推薦理由:一手新鮮,絕對(duì)干貨
代瀏覽器都內(nèi)置了專用動(dòng)畫技術(shù),Martin G?rner為您展現(xiàn)四種最棒的實(shí)例。
現(xiàn)代移動(dòng)操作系統(tǒng)將用戶接口動(dòng)畫化,并已達(dá)到了電腦端交互的標(biāo)準(zhǔn)——精選流暢的動(dòng)畫,體現(xiàn)出沉浸效果以及支持直觀的交互。我們都想當(dāng)然的認(rèn)為,可以設(shè)置一個(gè)列表,使之帶有運(yùn)動(dòng)特性,用手指輕輕一推,它就如同有重量和慣性一樣運(yùn)動(dòng)起來(lái),直到遇到邊緣再反彈回來(lái)一點(diǎn)。但是,在網(wǎng)絡(luò)上,我們還達(dá)不到這樣的效果。
接受事實(shí)吧,現(xiàn)有網(wǎng)上的動(dòng)畫經(jīng)常被視作UI災(zāi)難,還在使用二十年前陳舊的<blink>標(biāo)簽技術(shù)。加入Flash有點(diǎn)幫助,不過(guò)它缺乏HTML DOM集成,都變成了不美觀的800×600分辨率,并且JavaScript DOM操作還有其標(biāo)志性的5幀/秒(fps)動(dòng)畫率——真是絕望?。?/p>
改變
2013年,現(xiàn)代瀏覽器內(nèi)置了專用動(dòng)畫技術(shù),達(dá)到60 fps。是時(shí)候去忘掉過(guò)去,開始構(gòu)建美妙的UI動(dòng)畫體驗(yàn)了。我將展示四個(gè)動(dòng)畫技術(shù),幫助你決定,哪一個(gè)更適合你的項(xiàng)目。
讓我們從最簡(jiǎn)單的聲明式技術(shù)開始:CSS3。這里不需要JavaScript,存CSS,加上一點(diǎn)現(xiàn)代手段。
CSS通過(guò)兩種基本屬性來(lái)聲明動(dòng)畫:過(guò)渡和動(dòng)畫。過(guò)渡屬性通知瀏覽器計(jì)算兩種狀態(tài)(由各自CSS定義)間的中間幀。動(dòng)畫通過(guò)改變?cè)谻SS觸發(fā)。比如,當(dāng)你以編程方式改變它的層,或啟動(dòng)一個(gè):hover CSS。
當(dāng)縮略圖層從開始轉(zhuǎn)變到結(jié)束,圖像則從一處平滑的移動(dòng)到另一處,典型的表現(xiàn)為JavaScript DOM動(dòng)作的結(jié)果。
img { -webkit-transition: 1s; }.begin { left: 0px; }.end { left: 500px; }
動(dòng)畫屬性最常用于持續(xù)運(yùn)行的動(dòng)畫特效,它還允許自定義中間步驟的動(dòng)畫。
創(chuàng)建一個(gè)旋轉(zhuǎn)的圖像:
img {-webkit-animation: myAnim 3s infinite; }@-webkit-keyframes myAnim{ from {-webkit-transform: rotate(0deg) } 50% {/* possible intermediate positions at any % */} to {-webkit-transform: rotate(360deg) }}
利用大量CSS屬性制作動(dòng)畫具有無(wú)限的創(chuàng)造性,你可以根據(jù)意圖在邊框?qū)挾葍?nèi)任意創(chuàng)建動(dòng)畫。 不過(guò),大多數(shù)對(duì)動(dòng)畫有用的屬性都是幾何變換和不透明的。CSS3通過(guò)易操作的轉(zhuǎn)換屬性提供了全系列二維幾何變換:平移、旋轉(zhuǎn)、縮放和歪斜。
用旋轉(zhuǎn)、縮放和歪斜創(chuàng)建2D轉(zhuǎn)換:
webkit-transform:旋轉(zhuǎn)30度
webkit-transform:縮小50%
webkit-transform:歪斜-20度,再20度
接下來(lái)變得有趣了。如果你覺得在CSS中添加3D效果,技術(shù)上是為了粗體和斜體的設(shè)計(jì),這很愚蠢,請(qǐng)接著閱讀。通過(guò)擴(kuò)展幾何轉(zhuǎn)換到三維圖像將是一個(gè)很自然的方式,相同變換屬性還可以做平移X,Y,Z軸以及旋轉(zhuǎn)X,Y,Z軸。
3D旋轉(zhuǎn)圖像:
webkit-transform:Y軸旋轉(zhuǎn)45度
再加上點(diǎn)拋出動(dòng)畫效果,看上去就像是一個(gè)旋轉(zhuǎn)的三維立方體。
如果確實(shí)這般容易的話,就不會(huì)有任何趣味性了。設(shè)計(jì)師留了一點(diǎn)懸念,你可以試一下,只對(duì)一個(gè)圖像進(jìn)行旋轉(zhuǎn),瀏覽器默認(rèn)渲染出來(lái)的效果是不帶透視性的:
webkit-transform:Y軸旋轉(zhuǎn)45度
可以添加上透明屬性,默認(rèn)是無(wú)窮大極限值也是不帶有一點(diǎn)透明效果的。就如同靠近鏡頭的對(duì)象與很遠(yuǎn)距離外的對(duì)象看上去大小一樣。
為了確保圖像看上去更真實(shí),你還需要指定一個(gè)鏡頭與屏幕之間距離的值。加上-webkitperspective: 1000px就可以了。
要在一塊平面屏幕上呈現(xiàn)一個(gè)3D對(duì)象,首先畫出一條線連接眼鏡或相機(jī)與3D物理上的點(diǎn)。這條線與屏幕的交集就是相應(yīng)像素所在的位置。為了找到像素在屏幕上的坐標(biāo),利用泰勒斯定理,你需要空間中點(diǎn)的3D坐標(biāo)和相機(jī)與屏幕之間的距離(f在光學(xué)中也被稱為焦距)。這就是視角屬性提供的距離。如果這個(gè)距離是無(wú)限遠(yuǎn)的,你可以看到所有射線(眼球到3D點(diǎn)線)是水平緊密狀的,而且很遠(yuǎn)很遠(yuǎn)的對(duì)象在屏幕上的大小一樣。
現(xiàn)在我們有設(shè)置一個(gè)3D立方體的所有基礎(chǔ)了,利用六個(gè)圖像以及CSS 3D轉(zhuǎn)換,接下來(lái)就可以實(shí)現(xiàn)旋轉(zhuǎn)了。
這一步很簡(jiǎn)單:我們把一個(gè)三維旋轉(zhuǎn)封裝到一個(gè)div,將會(huì)產(chǎn)生如下效果:
瀏覽器執(zhí)行你讓它所做的步驟:在div渲染一個(gè)三維立方體,然后像一張平面圖片般在自身運(yùn)用3D旋轉(zhuǎn)。這是默認(rèn)效果,雖然不是你想要的。你要告訴瀏覽器運(yùn)用嵌套div來(lái)構(gòu)成3D轉(zhuǎn)換,-webkit-transform-style: preserve-3d屬性。通過(guò)這個(gè),我們就能得到想要的旋轉(zhuǎn)立方體了。
很容易在空間失去定位。我的建議是采用一個(gè)div,命名為SCENE。這就是透明屬性存放的位置。在內(nèi)部,放置一個(gè)命名為OBJECT的div,它應(yīng)當(dāng)擁有transform-style: preserve-3d屬性,并且該div就是你應(yīng)用轉(zhuǎn)換移動(dòng)整個(gè)對(duì)象的地方。最后,在該div內(nèi)部,使用3D轉(zhuǎn)換設(shè)置你想要的正面圖像,創(chuàng)建所需對(duì)象。在我們的例子中,立方體的六個(gè)面:
.SCENE { -webkit-perspective: 1000px; }.OBJECT{ -webkit-transform-style: preserve-3d; -webkit-transform: rotateX(20deg rotateY(120deg) rotateZ(50deg); /* replace this with an animation property if you want movement */}.FACE1 { -webkit-transform:translateX(150px)rotateY(90deg);}...
關(guān)于3D CSS轉(zhuǎn)換很棒的一點(diǎn)是CSS動(dòng)畫和過(guò)渡的完美結(jié)合。我們?cè)谶@留了一個(gè)練習(xí),讓旋轉(zhuǎn)立方體運(yùn)動(dòng)起來(lái),當(dāng)鼠標(biāo)光標(biāo)懸停其上時(shí),立方體自動(dòng)打開來(lái)。操作方法是:把立方體的面移動(dòng)到與中心一定距離的地方。第二組CSS屬性有一個(gè) :hover選擇器,將立方體的面放置在更遠(yuǎn)的距離。通過(guò)運(yùn)用第一種轉(zhuǎn)換屬性,你將看到立方體從中心盤旋打開,同時(shí)還保持旋轉(zhuǎn)(演示)。
HTML與CSS都是強(qiáng)大的動(dòng)畫技術(shù),但缺乏繪圖基元。SVG能夠彌補(bǔ)這點(diǎn),并擁有其獨(dú)特的動(dòng)畫標(biāo)簽。SVG動(dòng)畫部分被特定稱為同步多媒體集成語(yǔ)言(SMIL)。
首先,SVG是用于矢量基元的,比如矩形、圓形和貝塞爾曲線:
<svg> <rect x="5" y="5" width="140" height="140" stroke="#000000" strokewidth="4"fill="#AAAAFF" opacity="1"/></svg>
同樣可用于:
<line x1 y1 x2 y2><circle cx cy r><path d><image x y width height xlink:href>
其中一個(gè)基元,<path>標(biāo)簽,是SVG中最好用的。它允許你使用直線、弧和貝塞爾曲線定義任意路徑。路徑定義看上去想一個(gè)字母,如同Inkscape矢量圖形軟件生成的。對(duì)于SVG動(dòng)畫,你應(yīng)該理解這一點(diǎn)。
一個(gè)二次和三次貝塞爾曲線的例子:
<svg> <path d="M 30,240 Q 170,40 260,230" stroke="#F00" /> <path d="M 30,240 C 70,90 210,150 260,230" stroke="#F00" /></svg>
語(yǔ)法:
M x,y ? ? 新的起點(diǎn) (標(biāo)記)
L x,y ? ? ?到哪里的直線
Q cx, cy, x, y ?二次貝塞爾曲線到 (x,y)和一個(gè)控制點(diǎn)
C cx,cy, dx,dy, x,y 三次貝塞爾曲線到(x, y)和兩個(gè)控制點(diǎn)
A ? ? ? 橢圓弧
z ? ? ? 字符串最后,用于結(jié)束路徑
讓我們把這些矢量變得更生動(dòng)化。你可以查看演示,一個(gè)家伙踏著滑板翱翔于白云間。
沖浪板上下擺動(dòng),小人的嘴巴在大和更大的笑容間交替變化,眼睛滾動(dòng),瞳孔擴(kuò)張。這是SVG動(dòng)畫四種可能的類型。
最簡(jiǎn)單的一種SVG動(dòng)畫運(yùn)用<animate>標(biāo)簽,改變一種幾何形狀的一個(gè)參數(shù),在本例中,就是眼睛的半徑。
要使瞳孔擴(kuò)張,需要改變屬性列表值中的半徑值。
<circle cx="200" cy="205" r="80" > <animate dur="3s" attributeName="r" values="80; 150; 80" repeatCount="indefinite" /></circle>
方便的是變化的屬性還可以成為<path>標(biāo)簽。允許你創(chuàng)建一個(gè)動(dòng)畫路徑。 唯一的限制是兩個(gè)曲線之間要進(jìn)行轉(zhuǎn)換,必須是同一種類型且擁有相同數(shù)量的控制點(diǎn)。它們必須由相同位置上的同一個(gè)字母定義,唯一不同的只能是參數(shù)的改變。當(dāng)移動(dòng)小人的嘴巴時(shí),只有“微笑”和“大笑”位置被定義了。SVG動(dòng)畫將完成插值。
<path fill="#fff"> <animate attributeName="d" dur="2s" repeatCount="indefinite" values="m 0,0 c 1,15 -13,45 -45,45 -32,0 -44,-28 -44,-44 z; m 0,0 c -4,15 -66,106 -98,106 -32,0 3,-89 9,-105 z" /></path>
當(dāng)然,SVG還能進(jìn)行幾何變換,也能做成動(dòng)畫。這里的動(dòng)畫標(biāo)簽是<animate Transform>。你必須告訴它想要將哪里的轉(zhuǎn)變做成動(dòng)畫,還要提供一個(gè)分號(hào)分隔的所有關(guān)鍵位置的值列表。還可以組成動(dòng)畫轉(zhuǎn)換,你告訴瀏覽器使用additive=”sum” 屬性。
幾何轉(zhuǎn)換的動(dòng)畫:
<g> ... <!-- SVG primitives group --> <animateTransform dur="3s" repeatCount="indefinite" additive="sum" attributeName="transform" type="translate" values="0,0; 200,-130; -100,200; 0,0" /> <animateTransform dur="3s" repeatCount="indefinite" additive="sum" attributeName="transform" type="rotate" values="0; 20; -20; 0" /></g>
第三個(gè)和最后一個(gè)SVG動(dòng)畫標(biāo)簽也很有用。<animateMotion>用來(lái)引導(dǎo)對(duì)象沿著特定路徑運(yùn)動(dòng)。 它有一個(gè)隱藏的技巧稱為rotate=”auto”屬性。它讓對(duì)象不僅能夠遵循指定路徑,同時(shí)自身保持朝前,如同路上行駛的車輛一樣。
<g> ... <!-- SVG primitives group --> <animateMotion dur=”1s"repeatCount="indefinite" path="m 0,0 a 15,11 0 1 1 -30,0 15,11 0 1 1 30,0 z" /></g>
SMIL有大量控制動(dòng)畫特征。在它的JavaScript API中揭露pauseAnimations(), unpauseAnimations()和setCurrentTime(t) 函數(shù)在全局性開始/停止/暫停一個(gè)動(dòng)畫的功能。還在所有三種動(dòng)畫標(biāo)簽(<animate>, <animateTransform>, <animateMotion>)上指定了begin與end屬性。它們可以利用一個(gè)事件節(jié)點(diǎn)/用戶事件/動(dòng)畫事件的強(qiáng)大組合。你可以指定,動(dòng)畫在點(diǎn)擊之后的一秒結(jié)束或開始。
例如,下面這個(gè)SVG按鈕被點(diǎn)擊后有一個(gè)移動(dòng)的陰影效果:
<g id="buttonID"> <!-- SVG button artwork here --> <animate begin="buttonID.click" dur="1s"\ .../></g>
由聲明性動(dòng)畫轉(zhuǎn)換到編程性動(dòng)畫技術(shù),<canvas>標(biāo)簽是你的第一選擇。本文所提到的所有技術(shù)中,<canvas>標(biāo)簽最具有跨瀏覽器支持,瀏覽器廠商做了很多努力使之兼容60fps動(dòng)畫,以下是設(shè)置一個(gè)畫布的方法:
<canvas width="400" height="400" style="width: 400px; height: 400px;"></canvas>
第一個(gè)尺寸(標(biāo)簽屬性)設(shè)置了畫布的分辨率,這就是你所使用的坐標(biāo)空間。第二個(gè)尺寸(CSS屬性)是畫布出現(xiàn)在屏幕上的形狀大小。為什么不把畫布物理尺寸設(shè)置到100%分辨率,內(nèi)部坐標(biāo)空間不變,瀏覽器為任意窗口都能正確渲染圖畫?非常遺憾,瀏覽器將畫布內(nèi)容作為點(diǎn)陣圖來(lái)掃描的,任何擴(kuò)大范圍的結(jié)果都將導(dǎo)致模糊混亂的像素。于是,把這兩個(gè)值設(shè)置成相同的值是唯一可行的選項(xiàng)。
初始化畫布需要JavaScript中<canvas>元素,并在其上調(diào)用getContext('2d')函數(shù)。獲得的圖畫內(nèi)容對(duì)象被用來(lái)調(diào)用到畫布API。內(nèi)容是狀態(tài)性的,存儲(chǔ)三種不同的狀態(tài)信息:繪畫風(fēng)格,即時(shí)幾何轉(zhuǎn)換以及累計(jì)繪圖路徑。在畫布上進(jìn)行繪畫的方法是發(fā)布繪圖指令,不產(chǎn)生任何可見內(nèi)容,但在內(nèi)存中已創(chuàng)建了一個(gè)路徑,然后發(fā)布一個(gè)油墨指令(ctx.stroke(), ctx.fill() 或兩者皆有),就能顯示出路徑了。
畫布動(dòng)畫需要設(shè)置一個(gè)動(dòng)畫循環(huán),你應(yīng)當(dāng)基于requestAnimationFrame()函數(shù)(帶有正確的前綴)。該函數(shù)使瀏覽器能夠管理幀率,在瀏覽器選項(xiàng)卡隱藏時(shí)也能停止動(dòng)畫。
function runAnimation(){ yourWorld.draw() // this is your drawing code webkitRequestAnimationFrame(runAnimation);}
一般來(lái)說(shuō),畫布被用于動(dòng)畫的時(shí)候,對(duì)象的位置必須是在逐幀的基礎(chǔ)上才行,這是因?yàn)樗鼈兌际俏锢矸抡娴慕Y(jié)果。觀看box2dweb.js教程。仿真不斷改變仿真世界中對(duì)象的位置,動(dòng)畫循環(huán)周期性的在屏幕上展現(xiàn)當(dāng)前環(huán)境狀態(tài)。
在畫布動(dòng)畫中使用SVG精靈是一種很有用的技巧。一個(gè)任意復(fù)雜性的靜態(tài)矢量圖片在畫布上呈現(xiàn)都是繁瑣的,這樣做實(shí)際上可行,雖然不如發(fā)送一個(gè).svg到 ctx.drawImage()簡(jiǎn)單。出于模糊安全的原因,只有內(nèi)聯(lián)SVG支持,你必須在Blob API中使用它(代碼)。
SVG精靈能夠以任意比例展示其矢量美態(tài),但遺憾的是,只支持Chrome瀏覽器。
WebGL暴露瀏覽器運(yùn)行的JavaScript應(yīng)用程序OpenGL API,而不需要任何插件。理論上講,你只需要在<canvas> 元素上調(diào)用getContext(‘webgl’)(而不是之前的2d)就可以了。然而,WebGL非常大,并且API等級(jí)低。最重要的是,web版本沒有默認(rèn)的渲染路徑,這意味著你無(wú)法給它一個(gè)形狀,讓它使用適合的默認(rèn)值展示出來(lái)。所以你必須編寫著色器,使用GLSL語(yǔ)言編寫屏幕上出現(xiàn)的任何內(nèi)容。
幸運(yùn)的是我們有Three.js幫助。Three最初是由Mr.doob開發(fā)的庫(kù),用于一些Chrome演示(www.ro.me/www.chaostoperfection.com),但它是相對(duì)獨(dú)立的。它擁有所有的基礎(chǔ),以及內(nèi)置獨(dú)特的著色器,你就可以專注于其他有用的方面:相機(jī)、燈光、行動(dòng)。
首先要做的是編寫Three粘合代碼(很簡(jiǎn)單):
var renderer=new THREE.WebGLRenderer({antialias: true});renderer.setSize(width, height);renderer.setClearColorHex(0x000000, 0); // color,transparency// the renderer creates a canvas elementfor youdocument.whereeveryouwant.appendChild(renderer.domElement);
在lights和action之前,需創(chuàng)建camera和位置:
// arguments: FOV,viewAspectRatio, zNear, zFarvar camera=new THREE.PerspectiveCamera(35,width/height, 1, 10000);camera.position.z=300;
然后是light:
var light=new THREE.DirectionalLight(0xffffff, 1);//color, intensitylight.position.set(1, 1, 0.3); // direction
我們?cè)囍尸F(xiàn)一個(gè)立方體吧,3D對(duì)象在Three中被稱為網(wǎng)絡(luò),都由一個(gè)幾何體和一個(gè)材料構(gòu)成。
我們使用一個(gè)簡(jiǎn)單的結(jié)構(gòu):
var texture=THREE.ImageUtils.loadTexture(‘Fernando Togni.jpg’);var cube=new THREE.Mesh( new THREE.CubeGeometry(100, 100, 100), new THREE.MeshLambertMaterial({map: texture}) );
最后添加內(nèi)容,稱為渲染函數(shù)。
var scene=new THREE.Scene();scene.add(cube);scene.add(light);renderer.render(scene, camera);
這將為我們的立方體產(chǎn)生一個(gè)靜態(tài)圖像,為了讓它動(dòng)起來(lái),我們包裹渲染召集一個(gè)動(dòng)畫循環(huán),改變立方體在每一幀的位置。
function runAnimation(t){ // animate your objects depending on time cube.rotation.y=t/1000; cube.position.x=... renderer.render(scene, camera); // display requestAnimationFrame(runAnimation); // and loop}
推薦使用三維建模軟件例如Sketchup。Three識(shí)別幾類3D模型結(jié)構(gòu),包括COLLADA(.dae)具有廣泛行業(yè)支撐。下面是如何在Three中加載一個(gè)模型:
var loader=new THREE.ColladaLoader();loader.load("Android.dae", function(collada){ var model=collada.scene; model.position=...; // x, y, z model.rotation=...; // x, y, z scene.add(model);} );
再做一些努力,更換機(jī)器人外觀花式,Three提供蘭伯特和馮氏照明風(fēng)格,法線貼圖,凹凸貼圖,環(huán)境映射以及更多。
還可以使機(jī)器人運(yùn)動(dòng)起來(lái),具體步驟參考教程。
原文鏈接:http://www.gbtags.com/gb/share/2124.htm
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。