繪制圖形

Canvas


Canvas是HTML5新增的組件影涉,它就像一塊幕布膏秫,可以用JavaScript在上面繪制各種圖表侮措、動(dòng)畫(huà)等懈叹。

沒(méi)有Canvas的年代,繪圖只能借助Flash插件實(shí)現(xiàn)分扎,頁(yè)面不得不用JavaScript和Flash進(jìn)行交互澄成。有了Canvas,我們就再也不需要Flash了,直接使用JavaScript完成繪制墨状。

一個(gè)Canvas定義了一個(gè)指定尺寸的矩形框卫漫,在這個(gè)范圍內(nèi)我們可以隨意繪制:

<canvas id="test-canvas" width="300" height="200"></canvas>

由于瀏覽器對(duì)HTML5標(biāo)準(zhǔn)支持不一致,所以肾砂,通常在<canvas>內(nèi)部添加一些說(shuō)明性HTML代碼列赎,如果瀏覽器支持Canvas,它將忽略<canvas>內(nèi)部的HTML镐确,如果瀏覽器不支持Canvas包吝,它將顯示<canvas>內(nèi)部的HTML:

<canvas id="test-stock" width="300" height="200">
    <p>Current Price: 25.51</p>
</canvas>

在使用Canvas前,用canvas.getContext來(lái)測(cè)試瀏覽器是否支持Canvas:

<!-- HTML代碼 -->
<canvas id="test-canvas" width="200" heigth="100">
    <p>你的瀏覽器不支持Canvas</p>
</canvas>
'use strict';

var canvas = document.getElementById('test-canvas');
if (canvas.getContext) {
    console.log('你的瀏覽器支持Canvas!');
} else {
    console.log('你的瀏覽器不支持Canvas!');
}

Run

你的瀏覽器支持Canvas!

getContext('2d')方法讓我們拿到一個(gè)CanvasRenderingContext2D對(duì)象源葫,所有的繪圖操作都需要通過(guò)這個(gè)對(duì)象完成诗越。

var ctx = canvas.getContext('2d');

如果需要繪制3D怎么辦?HTML5還有一個(gè)WebGL規(guī)范息堂,允許在Canvas中繪制3D圖形:

gl = canvas.getContext("webgl");

本節(jié)我們只專(zhuān)注于繪制2D圖形嚷狞。

繪制形狀

我們可以在Canvas上繪制各種形狀。在繪制前荣堰,我們需要先了解一下Canvas的坐標(biāo)系統(tǒng):

[圖片上傳失敗...(image-1e1233-1592793107084)]

Canvas的坐標(biāo)以左上角為原點(diǎn)床未,水平向右為X軸,垂直向下為Y軸持隧,以像素為單位,所以每個(gè)點(diǎn)都是非負(fù)整數(shù)逃片。

CanvasRenderingContext2D對(duì)象有若干方法來(lái)繪制圖形:

'use strict';

var
    canvas = document.getElementById('test-shape-canvas'),
    ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 200, 200); // 擦除(0,0)位置大小為200x200的矩形屡拨,擦除的意思是把該區(qū)域變?yōu)橥该?ctx.fillStyle = '#dddddd'; // 設(shè)置顏色
ctx.fillRect(10, 10, 130, 130); // 把(10,10)位置大小為130x130的矩形涂色
// 利用Path繪制復(fù)雜路徑:
var path=new Path2D();
path.arc(75, 75, 50, 0, Math.PI*2, true);
path.moveTo(110,75);
path.arc(75, 75, 35, 0, Math.PI, false);
path.moveTo(65, 65);
path.arc(60, 65, 5, 0, Math.PI*2, true);
path.moveTo(95, 65);
path.arc(90, 65, 5, 0, Math.PI*2, true);
ctx.strokeStyle = '#0000ff';
ctx.stroke(path);

Run

繪制文本

繪制文本就是在指定的位置輸出文本,可以設(shè)置文本的字體褥实、樣式呀狼、陰影等,與CSS完全一致:

'use strict';

var
    canvas = document.getElementById('test-text-canvas'),
    ctx = canvas.getContext('2d');
    
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = '#666666';
ctx.font = '24px Arial';
ctx.fillStyle = '#333333';
ctx.fillText('帶陰影的文字', 20, 40);

Canvas除了能繪制基本的形狀和文本损离,還可以實(shí)現(xiàn)動(dòng)畫(huà)哥艇、縮放、各種濾鏡和像素轉(zhuǎn)換等高級(jí)操作僻澎。如果要實(shí)現(xiàn)非常復(fù)雜的操作貌踏,考慮以下優(yōu)化方案:

  • 通過(guò)創(chuàng)建一個(gè)不可見(jiàn)的Canvas來(lái)繪圖,然后將最終繪制結(jié)果復(fù)制到頁(yè)面的可見(jiàn)Canvas中窟勃;
  • 盡量使用整數(shù)坐標(biāo)而不是浮點(diǎn)數(shù)祖乳;
  • 可以創(chuàng)建多個(gè)重疊的Canvas繪制不同的層,而不是在一個(gè)Canvas中繪制非常復(fù)雜的圖秉氧;
  • 背景圖片如果不變可以直接用<img>標(biāo)簽并放到最底層眷昆。

i

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子亚斋,更是在濱河造成了極大的恐慌作媚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帅刊,死亡現(xiàn)場(chǎng)離奇詭異纸泡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)厚掷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)弟灼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人冒黑,你說(shuō)我怎么就攤上這事田绑。” “怎么了抡爹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵掩驱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我冬竟,道長(zhǎng)欧穴,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任泵殴,我火速辦了婚禮涮帘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笑诅。我一直安慰自己调缨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布吆你。 她就那樣靜靜地躺著弦叶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪妇多。 梳的紋絲不亂的頭發(fā)上伤哺,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音者祖,去河邊找鬼立莉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛七问,可吹牛的內(nèi)容都是我干的桃序。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼烂瘫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼媒熊!你這毒婦竟也來(lái)了奇适?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤芦鳍,失蹤者是張志新(化名)和其女友劉穎嚷往,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體柠衅,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皮仁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了菲宴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贷祈。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖喝峦,靈堂內(nèi)的尸體忽然破棺而出势誊,到底是詐尸還是另有隱情,我是刑警寧澤谣蠢,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布粟耻,位于F島的核電站,受9級(jí)特大地震影響眉踱,放射性物質(zhì)發(fā)生泄漏挤忙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一谈喳、第九天 我趴在偏房一處隱蔽的房頂上張望册烈。 院中可真熱鬧,春花似錦婿禽、人聲如沸赏僧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)次哈。三九已至胎署,卻和暖如春吆录,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背琼牧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工恢筝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巨坊。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓撬槽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親趾撵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侄柔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353