【基礎(chǔ)系列】Canvas專題

1 Canvas接口元素定義

1.1 getContext()方法

????????為了在canvas上繪制藻雌,你必須先得到一個畫布上下文對象的引用偎球,用本方法即可完成這一操作瞳秽,格式如下:

context = canvas . getContext(contextId)

????????方法返回一個指定contextId的上下文對象联予,如果指定的id不被支持啼县,則返回null,當(dāng)前唯一被強制必須支持的是“2d”沸久,也許在將來會有“3d”季眷,注意,指定的id是大小寫敏感的卷胯。

1.2 toDataURL()方法

????????返回一張使用canvas繪制的圖片子刮,返回值符合data:URL格式,格式如下:

url = canvas . toDataURL( [ type, ... ])

????????規(guī)范規(guī)定,在未指定返回圖片類型時挺峡,返回的圖片格式必須為PNG格式葵孤,如果canvas沒有任何像素,則返回值為:“data:,”橱赠,這是最短的data:URL尤仍,在text/plain資源中表現(xiàn)為空字符串。type的可以在image/png狭姨,image/jpeg,image/svg+xml等 MIME類型中選擇宰啦。如果是image/jpeg,可以有第二個參數(shù)饼拍,如果第二個參數(shù)的值在0-1之間赡模,則表示JPEG的質(zhì)量等級,否則使用瀏覽器內(nèi)置默認(rèn)質(zhì)量等級惕耕。

????????下面的代碼可以從ID為codeex的canvas中取得繪制內(nèi)容纺裁,并作為DataURL傳遞給img元素,并顯示司澎。

var canvas =? document.getElementById('codeex');

var url = canvas.toDataURL();

//idmyimg的圖片元素

myimg.src = url;

2 二維繪圖上下文

????????當(dāng)使用一個canvas元素的getContext(“2d”)方法時欺缘,返回的是CanvasRenderingContext2D對象,其內(nèi)部表現(xiàn)為笛卡爾平面坐標(biāo)挤安,并且左上角坐標(biāo)為(0,0)谚殊,在本平面中往右則x坐標(biāo)增加和往下方y(tǒng)坐標(biāo)增加。每一個canvas元素僅有一個上下文對象蛤铜。其接口如下:

interface? CanvasRenderingContext2D {

// back-reference to the canvas

??? readonly attribute HTMLCanvasElement? canvas;

// state

??? void restore(); // pop state stack and? restore state

??? void save(); // push state on state stack

// transformations (default?transform is the identity matrix)

??? void rotate(in float angle);

??? void scale(in float x, in float y);

??? void setTransform(in float m11, in float? m12, in float m21, in float m22, in float dx, in float dy);

??? void transform(in float m11, in float? m12, in float m21, in float m22, in float dx, in float dy);

??? void translate(in float x, in float y);

// compositing

??? attribute float globalAlpha; // (default? 1.0)

??? attribute DOMString? globalCompositeOperation; // (default source-over)

// colors and styles

attribute? any fillStyle; // (default black)

??? attribute any strokeStyle; // (default? black)

??? CanvasGradient createLinearGradient(in float? x0, in float y0, in float x1, in float y1);

??? CanvasGradient createRadialGradient(in? float x0, in float y0, in float r0, in float x1, in float y1, in float r1);

??? CanvasPattern createPattern(in? HTMLImageElement image, in DOMString repetition);

??? CanvasPattern? createPattern(in HTMLCanvasElement image, in DOMString repetition);

??? CanvasPattern createPattern(in? HTMLVideoElement image, in DOMString repetition);

// line styles

??? attribute DOMString lineCap; //? "butt", "round", "square" (default? "butt")

??? attribute DOMString lineJoin; //? "miter", "round", "bevel" (default? "miter")

??? attribute float lineWidth; // (default 1)

??? attribute float miterLimit; // (default? 10)

// shadows

??? attribute float shadowBlur; // (default? 0)

??? attribute DOMString shadowColor; //? (default transparent black)

??? attribute float shadowOffsetX; //? (default 0)

??? attribute float shadowOffsetY; //? (default 0)

// rects

??? void clearRect(in float x, in float y, in? float w, in float h);

??? void fillRect(in float x, in float y, in? float w, in float h);

??? void strokeRect(in float x, in float y,? in float w, in float h);

// Complex shapes (paths) API

??? void arc(in float x, in float y, in float? radius, in float startAngle,??????in? float endAngle, in boolean anticlockwise);

??? void arcTo(in float x1, in float y1, in? float x2, in float y2, in float radius);

??? void beginPath();

??? void bezierCurveTo(in float cp1x, in? float cp1y, in float cp2x, in float cp2y, in float x, in float y);

??? void clip();

??? void closePath();

??? void fill();

??? void lineTo(in float x, in float y);

??? void moveTo(in float x, in float y);

??? void quadraticCurveTo(in float cpx, in? float cpy, in float x, infloat y);

??? void rect(in float x, in float y, in float? w, in float h);

??? void stroke();

??? boolean isPointInPath(in float x, in? float y);

// text

??? attribute DOMString font; // (default? 10px sans-serif)

??? attribute DOMString textAlign; //? "start", "end", "left", "right",? "center" (default: "start")

??? attribute DOMString textBaseline; //? "top", "hanging", "middle",? "alphabetic", "ideographic", "bottom" (default:? "alphabetic")

??? void fillText(in DOMString text, in float? x, in float y, optional in????float? maxWidth);

??? TextMetrics measureText(in DOMString? text);

??? void strokeText(in DOMString text, in? float x, in float y, optional in float maxWidth);

// drawing images

??? void drawImage(in HTMLImageElement image,? in float dx, in float dy, optional in float dw, in float dh);

??? void drawImage(in HTMLImageElement image,? in float sx, in float sy, in float sw, in float sh, in float dx, in float dy,? in float dw, in float dh);

??? void drawImage(in HTMLCanvasElement? image, in float dx, in float dy, optional in float dw, in float dh);

??? void drawImage(in HTMLCanvasElement? image, in float sx, in float sy, in float sw, in float sh, in float dx, in? float dy, in float dw, in float dh);

??? void drawImage(in HTMLVideoElement image,? in float dx, in float dy, optional in float dw, in float dh);

??? void drawImage(in HTMLVideoElement image,? in float sx, in float sy, in float sw, in float sh, in float dx, in float dy,? in float dw, in float dh);

// pixel manipulation

??? ImageData createImageData(in float sw, in? float sh);

??? ImageData createImageData(in ImageData? imagedata);

??? ImageData getImageData(in float sx, in? float sy, in float sw, in float sh);

??? void putImageData(in ImageData imagedata,? in float dx, in float dy, optional in float dirtyX, in float dirtyY, in float? dirtyWidth, in float dirtyHeight);

};

?

interface CanvasGradient {

// opaque object

??? void addColorStop(in float offset, in? DOMString color);

};


interface CanvasPattern {

// opaque object

};


interface TextMetrics {

??? readonly attribute float width;

};


interface ImageData {

??? readonly attribute CanvasPixelArray data;

??? readonly attribute unsigned long height;

??? readonly attribute unsigned long width;

};


interface CanvasPixelArray {

??? readonly attribute unsigned long length;

??? getter octet (in unsigned long index);

??? setter void (in unsigned long index, in? octet value);

};


2.1 canvas的狀態(tài)

??? 每個上下文都包含一個繪圖狀態(tài)的堆嫩絮,繪圖狀態(tài)包含下列內(nèi)容:

????1、當(dāng)前的transformation matrix.

????2围肥、當(dāng)前的clipping region.

????3剿干、當(dāng)前的屬性值:fillStyle, font, globalAlpha, globalCompositeOperation, lineCap, lineJoin, lineWidth, miterLimit, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY, strokeStyle, textAlign, textBaseline

????????注:當(dāng)前path和當(dāng)前bitmap不是繪圖狀態(tài)的一部分,當(dāng)前path是持久存在的穆刻,僅能被beginPath()復(fù)位置尔,當(dāng)前bitmap是canvas的屬性,而非繪圖上下文氢伟。

context . restore() //彈出堆最上面保存的繪圖狀態(tài)

context . save() //在繪圖狀態(tài)堆上保存當(dāng)前繪圖狀態(tài)

????????繪圖狀態(tài)可以看作當(dāng)前畫面應(yīng)用的所有樣式和變形的一個快照榜轿。而狀態(tài)的應(yīng)用則可以避免繪圖代碼的過度膨脹。

2.1.1 context . restore()


2.1.2 context . save()


2.2 轉(zhuǎn)換(Transformations)

? ? ? ? 當(dāng)建立形狀和路徑時朵锣,轉(zhuǎn)換矩陣被應(yīng)用到其坐標(biāo)上谬盐。轉(zhuǎn)換的執(zhí)行順序是嚴(yán)格按順序的(注:原文是反向,經(jīng)試驗應(yīng)該是按調(diào)用順序的)诚些。

????????在做轉(zhuǎn)換/變形之前先保存狀態(tài)是一個良好的習(xí)慣飞傀。大多數(shù)情況下,調(diào)用restore 方法比手動恢復(fù)原先的狀態(tài)要簡單得多。

2.2.1 context . rotate(angle)

context . rotate(angle) //按給定的弧度旋轉(zhuǎn),按順時針旋轉(zhuǎn)

rotate方法旋轉(zhuǎn)的中心始終是canvas的原點砸烦,如果要改變它犀被,需要使用translate方法。


2.2.2 context .scale(x, y)

????????context . scale(x, y) //按給定的縮放倍率縮放外冀,1.0,為不變,參數(shù)比1.0小表示縮小掀泳,否則表示放大雪隧。默認(rèn)情況下,canvas的1 單位就是1 個像素员舵。舉例說脑沿,如果我們設(shè)置縮放因子是0.5,1個單位就變成對應(yīng)0.5 個像素马僻,這樣繪制出來的形狀就會是原先的一半庄拇。同理,設(shè)置為2.0 時韭邓,1個單位就對應(yīng)變成了2 像素措近,繪制的結(jié)果就是圖形放大了2倍。


2.2.3 context . setTransform(m11, m12, m21, m22, dx, dy)

context . setTransform(m11, m12, m21, m22, dx, dy) //重設(shè)當(dāng)前的轉(zhuǎn)換


2.2.4 context . transform(m11, m12, m21, m22, dx, dy)

context . transform(m11, m12, m21, m22, dx, dy)

//矩陣變換女淑,結(jié)果等于當(dāng)前的變形矩陣乘上

m11 m21 dx

m12 m22 dy

0? ? ? 0? ? ? ?1

后的結(jié)果


2.2.5 context . translate(x, y)

context . translate(x, y) //可以理解為偏移瞭郑,向x,y方向偏移指定的量,其用來移動Canvas的原點到一個指定的值

2.2.5.1 示例

????????下面是一個利用translate方法進行繪制螺旋圖案的例子:

//繪制螺旋圖案的函數(shù)

function?drawSpirograph(ctx,R,r,O){

??? var x1 = R-O;

??? var y1 = 0;

??? var i = 1;

??? ctx.beginPath();

??? ctx.moveTo(x1,y1);

??? do {

??????? if (i>20000) break;

??????? var x2 = (R+r)*Math.cos(i*Math.PI/72)? - (r+O)*Math.cos(((R+r)/r)*(i*Math.PI/72))

??????? var y2 = (R+r)*Math.sin(i*Math.PI/72)? - (r+O)*Math.sin(((R+r)/r)*(i*Math.PI/72))

??????? ctx.lineTo(x2,y2);

??????? x1 = x2;

??????? y1 = y2;

??????? i++;

??? } while (x2 != R-O && y2 != 0 );

??? ctx.stroke();

}


//調(diào)用部分代碼

context.fillRect(0,0,300,300);

for (var i=0;i<3;i++) {

??? for (var j=0;j<3;j++) {

??????? context.save();

??????? context.strokeStyle =? "#9CFF00";

??????? context.translate(50+j*100,50+i*100);

??????? drawSpirograph(context,20*(j+2)/(j+1),-8*(i+3)/(i+1),10);

??????? context.restore();

??? }

}


2.3 合成(Compositing)

2.3.1 context . globalAlpha

context . globalAlpha [ = value ] //0-1.0之間的數(shù)據(jù),設(shè)定圖像的透明度


2.3.2 context . globalCompositeOperation

context . globalCompositeOperation [ = value ]

//設(shè)定重疊圖像的覆蓋方式鸭你,可以設(shè)定為(注屈张,值大小寫敏感):

注意:下面所有圖例中,B(藍(lán)色方塊)是先繪制的袱巨,即“已有的canvas 內(nèi)容”阁谆,A(紅色圓形)是后面繪制,即“新圖形”愉老。


2.4? 顏色和風(fēng)格

2.4.1 context. fillStyle

context . fillStyle [ = value ] //返回填充形狀的當(dāng)前風(fēng)格场绿,能被設(shè)置以用來改變當(dāng)前的填充風(fēng)格,其值可以是CSS顏色字串俺夕,也可以是CanvasGradient或者CanvasPattern對象裳凸,非法的值將被忽略。


2.4.2 context. strokeStyle

context . strokeStyle [ = value ] //返回當(dāng)前描繪形狀的風(fēng)格劝贸,能被設(shè)置姨谷,其值同上。

????????設(shè)置Javascript例子如下:

context.strokeStyle="#99cc33";

context.fillStyle='rgba(50,0,0,0.7)';

context.lineWidth=10;

context.fillRect(20,20,100,100);

context.strokeRect(20,20,100,100);


????????繪制的圖形如下所示映九。


2.4.3 gradient . addColorStop(offset, color)

gradient . addColorStop(offset, color) //在給定偏移的地方增加一個漸變顏色點梦湘,偏移量取值范圍為0-1.0之間,否則產(chǎn)生一個INDEX_SIZE_ERR的異常,color為DOM字符串捌议,如果不能解析哼拔,則拋出一個SYNTAX_ERR的異常。

2.4.4 context . createLinearGradient(x0, y0, x1, y1)

gradient = context . createLinearGradient(x0, y0, x1, y1) //建立一個線性漸變瓣颅,如果任何一個參數(shù)不是有限值倦逐,則拋出一個NOT_SUPPORTED_ERR的異常。

2.4.4.1 addColorStop()

? ??定義和用法

????????addColorStop()方法規(guī)定 gradient 對象中的顏色和位置宫补。

????????addColorStop()方法與 createLinearGradient()createRadialGradient() 一起使用檬姥。

? ??????注釋:您可以多次調(diào)用addColorStop() 方法來改變漸變。如果您不對 gradient 對象使用該方法粉怕,那么漸變將不可見健民。為了獲得可見的漸變,您需要創(chuàng)建至少一個色標(biāo)贫贝。

? ??JavaScript語法:? ??

gradient.addColorStop(stop,?color);

? ??參數(shù)值

? ??????參數(shù)描述

? ??????stop介于 0.0 與 1.0 之間的值秉犹,表示漸變中開始與結(jié)束之間的位置。

? ??????color在結(jié)束位置顯示的 CSS 顏色值

2.4.4.2 示例1

????????設(shè)置Javascript例子如下:

var? gradient = context.createLinearGradient(0, 2, 420, 2);

gradient.addColorStop(0, 'rgba(200, 0, 0, 0.8)');

gradient.addColorStop(0.5, 'rgba(0, 200, 0, 0.7)');

gradient.addColorStop(1, 'rgba(200, 0, 200, 0.9)');

context.strokeStyle = "#99cc33";

context.fillStyle=?gradient; //copyright codeex.cn

context.lineWidth = 10;

context.fillRect(20, 20, 400, 100);

context.strokeRect(20, 20, 400, 100);


????????繪制的圖形如下所示稚晚。

2.4.4.3 示例——通過多個addColorStop() 方法來定義漸變

????????通過多個 addColorStop() 方法來定義漸變:

var c=document.getElementById("myCanvas");

var ctx=c.getContext("2d");

var grd=ctx.createLinearGradient(0,0,170,0);

grd.addColorStop(0,"black");

grd.addColorStop("0.3","magenta");

grd.addColorStop("0.5","blue");

grd.addColorStop("0.6","green");

grd.addColorStop("0.8","yellow");

grd.addColorStop(1,"red");


ctx.fillStyle=grd;

ctx.fillRect(20,20,150,100);


2.4.5 context. createRadialGradient(x0, y0, r0, x1, y1, r1)

gradient = context . createRadialGradient(x0, y0, r0, x1, y1, r1) //建立一個徑向漸變崇堵,如果任何一個參數(shù)不是有限值,則拋出一個NOT_SUPPORTED_ERR的異常客燕。假如r0或r1為負(fù)值筑辨,則拋出INDEX_SIZE_ERR的異常。

2.4.5.1 繪制過程

????????createRadialGradient(x0,y0,r0,x1,y1,r1)方法有六個參數(shù)幸逆,前三個參數(shù)表示開始的圓棍辕,其圓點在(x0,y0),半徑為r0,后三個表示結(jié)束的圓还绘,參數(shù)意義同上楚昭。其繪制過程如下:

????1. 如果起始圓和結(jié)束圓重疊,則不繪制任何東西拍顷,并終止步驟抚太;

????2. x(w) = (x1-x0)w + x0 y(w) = (y1-y0)w + y0 r(w) =(r1-r0)w + r0在以(x(w),y(w))為圓點,r(w)為半徑的圓周上所有點的顏色均為Color(w)昔案。

????3. 對于任意的w取值(-∞ -- +∞)尿贫,確保r(w)>0,總是可以知道畫布中已知點的顏色。

????????言而總之:這個效果就是建立一個圓錐體(手電筒效果)渲染效果踏揣,圓錐體的開始圓使用開始顏色偏移量為0庆亡,圓錐體的結(jié)束圓使用顏色偏移量為1.0,面積外的顏色均使用透明黑捞稿。


2.4.5.2 示例

????????設(shè)置Javascript例子如下:

var gradient? = context.createRadialGradient (100,100, 20, 300,300,80);

gradient.addColorStop(0,'rgba(200,0,0,0.8)');

gradient.addColorStop(1,'rgba(200,0,200,0.9)');

context.strokeStyle="#99cc33";

context.fillStyle= gradient;? ??//'rgba(50,0,0,0.7)';

context.lineWidth=10;

context.fillRect(10,10,400,400);

context.strokeRect(10,10,400,400);


繪制的圖形如下所示又谋。

2.4.6 context . createPattern(image, repetition)

????????上面提到可以作為渲染風(fēng)格還有圖案對象:CanvasPattern,其調(diào)用格式如下:

pattern = context . createPattern(image, repetition)

????????本方法用指定的圖像和重復(fù)方向建立一個畫布圖案對象拼缝,image參數(shù)可以為img,canvas,video元素中的任一個,如果不滿足此條件彰亥,則拋出TYPE_MISMATCH_ERR異常咧七,如果圖片編碼未知或沒有圖像數(shù)據(jù),則拋出INVALID_STATE_ERR異常任斋;第二個參數(shù)可以是下列值:

????repeat????默認(rèn)參數(shù)继阻,如果為空,則為此參數(shù)废酷,表示兩個方向重復(fù)

????repeat-x????僅水平重復(fù)

????repeat-y????僅垂直重復(fù)

????no-repeat????不重復(fù)

????????如果image參數(shù)是一個HTMLImageElement對象穴翩,但對象的complete屬性是false,則執(zhí)行時拋出INVLAID_STATE_ERR異常锦积;

????????如果image參數(shù)是一個HTMLVideoElement對象,但其readyState屬性是HAVE_NOTHING或HAVE_METADATA歉嗓,則執(zhí)行時拋出拋出INVLAID_STATE_ERR異常丰介;

????????如果image參數(shù)是一個HTMLCanvasElement對象,但其width屬性或height屬性是0鉴分,則執(zhí)行時拋出拋出INVLAID_STATE_ERR異常哮幢。

????????圖案的繪制時從左上角開始的,根據(jù)不同的參數(shù)進行重復(fù)繪制志珍。如果傳遞的圖片是動畫橙垢,則選取海報或第一幀作為其繪制圖案源,如果使用HTMLVideoElement為對象伦糯,則當(dāng)前播放位置幀被作為圖案源柜某。


2.4.6.1 示例

????????設(shè)置HTML的核心代碼如下:

????????設(shè)置Javascript例子如下:

var imgSrc = document.getElementById('psrc')

var pattern =? context.createPattern(imgSrc,'repeat');

context.strokeStyle="#99cc33";

context.fillStyle= pattern;//by codeex.cn

context.lineWidth=10;

context.fillRect(10,10,200,220);

context.strokeRect(10,10,200,220);

????????在IE9中的顯示效果如圖所示:


2.5 線風(fēng)格

2.5.1 context . lineCap

????????操作線風(fēng)格的方法有4個,格式如下:

context . lineCap [ = value ] //返回或設(shè)置線段的箭頭樣式敛纲,僅有三個選項:butt(默認(rèn)值),round,square;其他值忽略

2.5.2 context . lineJoin

context . lineJoin [ = value ] ///返回或設(shè)置線段的連接方式喂击,僅有三個選項:miter(默認(rèn)值),round,bevel淤翔;其他值忽略


2.5.3 context . lineWidth

context . lineWidth [ = value ] //返回或設(shè)置線段的線寬翰绊,非大于0的值被忽略;默認(rèn)值為1.0旁壮;


2.5.4 context . miterLimit

context . miterLimit [ = value ] //返回或設(shè)置線段的連接處的斜率监嗜,非大于0的值被忽略;默認(rèn)值為10.0抡谐。本屬性翻譯不夠準(zhǔn)確裁奇,請參看英文部分


2.5.5 線寬

????????線寬是指給定路徑的中心到兩邊的粗細(xì)。換句話說就是在路徑的兩邊各繪制線寬的一半麦撵。因為畫布的坐標(biāo)并不和像素直接對應(yīng)框喳,當(dāng)需要獲得精確的水平或垂直線的時候要特別注意课幕。

????????想要獲得精確的線條,必須對線條是如何描繪出來的有所理解五垮。見下圖乍惊,用網(wǎng)格來代表canvas 的坐標(biāo)格,每一格對應(yīng)屏幕上一個像素點放仗。在第一個圖中润绎,填充了 (2,1) 至 (5,5) 的矩形,整個區(qū)域的邊界剛好落在像素邊緣上诞挨,這樣就可以得到的矩形有著清晰的邊緣莉撇。

????????如果你想要繪制一條從 (3,1) 到 (3,5),寬度是 1.0的線條惶傻,你會得到像第二幅圖一樣的結(jié)果棍郎。實際填充區(qū)域(深藍(lán)色部分)僅僅延伸至路徑兩旁各一半像素。而這半個像素又會以近似的方式進行渲染银室,這意味著那些像素只是部分著色涂佃,結(jié)果就是以實際筆觸顏色一半色調(diào)的顏色來填充整個區(qū)域(淺藍(lán)和深藍(lán)的部分)。

????????要解決這個問題蜈敢,你必須對路徑施以更加精確的控制辜荠。已知粗 1.0 的線條會在路徑兩邊各延伸半像素拗军,那么像第三幅圖那樣繪制從(3.5,1) 到 (3.5,5) 的線條伺糠,其邊緣正好落在像素邊界,填充出來就是準(zhǔn)確的寬為1.0 的線條明场。

????????對于那些寬度為偶數(shù)的線條否过,每一邊的像素數(shù)都是整數(shù)午笛,那么你想要其路徑是落在像素點之間(如那從(3,1) 到 (3,5)) 而不是在像素點的中間。如果不是的話苗桂,端點上同樣會出現(xiàn)半渲染的像素點季研。

2.6 陰影(Shadows)

????????有關(guān)陰影的四個全局屬性將影響所有的繪畫操作。有關(guān)定義如下:

context . shadowBlur [ = value ] //返回或設(shè)置陰影模糊等級誉察,非大于等于0的值被忽略与涡;

context . shadowColor [ = value ] //返回或設(shè)置陰影顏色

context . shadowOffsetX [ = value ]

context . shadowOffsetY [ = value ] //返回或設(shè)置陰影的偏移量

????????注意:上面的值均不受坐標(biāo)轉(zhuǎn)換的影響,可以看做是絕對值持偏。

????????在上面的例子中增加下列語句驼卖,可以得到設(shè)置陰影的圖像:

context.shadowBlur=7;

context.shadowColor='rgb(200,0,0)';

context.shadowOffsetX = 3;

context.shadowOffsetY=3;


2.7 簡單形狀(矩形)

????????形狀的繪制不影響當(dāng)前路徑(path),形狀是剪切區(qū)域的主題鸿秆,也是陰影(Shadow)效果酌畜,全局透明(alpha),全局組合(composition)操作等的主題卿叽。其由下面三個方法來進行簡單的操作:

2.7.1 context. clearRect(x, y, w, h)

context. clearRect(x, y, w, h) \\在給定的矩形內(nèi)清除所有的像素為透明黑(transparentblack)

2.7.2 context. fillRect(x, y, w, h)

context. fillRect(x, y, w, h) //用當(dāng)前的填充風(fēng)格填充給定的區(qū)域

2.7.3 context . strokeRect(x, y, w, h)

context. strokeRect(x, y, w, h) //使用當(dāng)前給定的線風(fēng)格桥胞,繪制一個盒子區(qū)域恳守,影響其繪制風(fēng)格的有:strokeStyle,lineWidth贩虾,lineJoin催烘,miterLimit(可能)。

2.8 復(fù)雜形狀(路徑-paths)

????????繪圖上下文總有一個當(dāng)前路徑缎罢,并且是僅此一個伊群,它不是繪圖狀態(tài)的一部分。

????????一個路徑有0個或多個子路徑列表策精。每個子路徑包含一個或多個點列表(這些點組成直的或彎曲的線段)舰始,和一個標(biāo)識子路徑是否閉合的標(biāo)志。少于兩個點的子路徑在繪圖時被忽略咽袜。操作這些形狀的方法稍微多些丸卷,如下所示:

????????默認(rèn)情況下,圖形上下文的路徑有0個子路徑询刹。


2.8.1 路徑起始函數(shù)

????調(diào)用格式:

context . beginPath() //清空子路徑

context . closePath() //閉合路徑


????????方法概述:

2.8.1.1 context. beginPath()

beginPath方法重設(shè)繪圖上下文的子路徑列表谜嫉,并清空所有的子路徑。


2.8.1.2 context. closePath()

????????ClosePath方法在繪圖上下文如果沒有子路徑時范抓,什么也不做;否則食铐,它先把最后一個子路徑標(biāo)示為閉合匕垫,然后建立一個包含最后子路徑的第一個點的子路徑,并加入到繪圖上下文虐呻。有點拗口象泵,其一般可以看為,假如最后一個子路徑斟叼,我們命名為spN偶惠,假設(shè)spN有多個點,則用直線連接spN的最后一個點和第一個點朗涩,然后關(guān)閉此路徑和moveTo到第一個點忽孽。


2.8.2 繪制函數(shù)

????????調(diào)用格式:

context . stroke()

context . fill()

context . clip()

????????方法概述:


2.8.2.1 context. stroke()

????????stroke方法使用lineWidth,lineCap谢床,lineJoin兄一,以及strokeStyle對所有的子路徑進行填充。

2.8.2.2 context. fill()

????????fill方法使用fillStyle方式填充子路徑识腿,未閉合的子路徑在填充式按照閉合方式填充出革,但并不影響實際的子路徑集合。

2.8.2.3 context. clip()

????????clip方法使用計算所有的子路徑而建立新的剪切區(qū)域渡讼,未閉合的子路徑在填充式按照閉合方式填充骂束,但并不影響實際的子路徑集合耳璧,新的剪切區(qū)域?qū)⑻鎿Q當(dāng)前的剪切區(qū)域。

2.8.3 剪切(clip)

????????裁切路徑和普通的 canvas 圖形差不多展箱,不同的是它的作用是遮罩旨枯,用來隱藏沒有遮罩的部分。如下圖所示析藕。紅邊五角星就是裁切路徑召廷,所有在路徑以外的部分都不會在canvas 上繪制出來。

????????如果和上面介紹的 globalCompositeOperation 屬性作一比較账胧,它可以實現(xiàn)與source-in 和 source-atop 差不多的效果竞慢。最重要的區(qū)別是裁切路徑不會在canvas 上繪制東西,而且它永遠(yuǎn)不受新圖形的影響治泥。這些特性使得它在特定區(qū)域里繪制圖形時相當(dāng)好用筹煮。

2.8.3.1 隨機星星示例

????????效果圖:

????????首先,我畫了一個與 canvas 一樣大小的黑色方形作為背景居夹,然后移動原點至中心點败潦。然后用 clip方法創(chuàng)建一個弧形的裁切路徑。裁切路徑也屬于 canvas 狀態(tài)的一部分准脂,可以被保存起來劫扒。如果我們在創(chuàng)建新裁切路徑時想保留原來的裁切路徑,我們需要做的就是保存一下canvas 的狀態(tài)狸膏。

????????裁切路徑創(chuàng)建之后所有出現(xiàn)在它里面的東西才會畫出來沟饥。在畫線性漸變時這個就更加明顯了。然后在隨機位置繪制50 大小不一(經(jīng)過縮放)的顆湾戳,當(dāng)然也只有在裁切路徑里面的星星才會繪制出來贤旷。

????????代碼如下:

function draw()? {

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

??? ctx.fillRect(0,0,150,150);

??? ctx.translate(75,75);

// Create a? circular clipping path

??? ctx.beginPath();

??? ctx.arc(0,0,60,0,Math.PI*2,true);

??? ctx.clip();

// draw? background

??? var lingrad = ctx.createLinearGradient(0,-75,0,75);

??? lingrad.addColorStop(0, '#232256');

??? lingrad.addColorStop(1, '#143778');

??? ctx.fillStyle = lingrad;

??? ctx.fillRect(-75,-75,150,150);

// draw stars

??? for (var j=1;j<50;j++){

??????? ctx.save();

??????? ctx.fillStyle = '#fff';

??????? ctx.translate(75-Math.floor(Math.random()*150),? 75-Math.floor (Math. random () *150));

??????? drawStar(ctx,Math.floor(Math.random()*4)+2);

??????? ctx.restore();

??? }

}


function? drawStar(ctx,r){

??? ctx.save();

??? ctx.beginPath()

??? ctx.moveTo(r,0);

??? for (var i=0;i<9;i++){

??????? ctx.rotate(Math.PI/5);

??????? if(i%2 == 0) {

??????????? ctx.lineTo((r/0.525731)*0.200811,0);

??????? } else {

??????????? ctx.lineTo(r,0);

??????? }

??? }

??? ctx.closePath();

??? ctx.fill();

??? ctx.restore();

}

2.8.4 輔助方法—context. isPointInPath(x, y)

????????調(diào)用格式:

context . isPointInPath(x, y)


????????方法概述:

????????給定的坐標(biāo)(x,y)是否在當(dāng)前路徑中,坐標(biāo)(x砾脑,y)為繪圖坐標(biāo)系坐標(biāo)幼驶,并不受轉(zhuǎn)換的影響。

2.8.5 moveTo方法

????調(diào)用格式:

context . moveTo(x, y)

????方法概述:

????????建立新的子路徑韧衣,并制定其第一個點為(x,y)盅藻。

2.8.6 lineTo方法

????調(diào)用格式:

context . lineTo(x, y)

????方法概述:

????????如果繪圖上下文沒有子路徑,則其等同于moveTo(x,y),否則畅铭,其建立一條在子路徑最后一個點到給定點的直線萧求,并增加(x,y)到子路徑中。

2.8.7 rect方法

????調(diào)用格式:

context . rect(x, y, w, h)

????方法概述:

????????本方法建立二個新的子路徑顶瞒,第一個子路徑包含四個點:(x夸政,y),(x+w榴徐,y)守问,(x+w匀归,y+h),(x耗帕,y+h)穆端,四個點的連接方式為直線,該子路徑被標(biāo)示為閉合路徑仿便;最后再增加一個子路徑体啰,其僅有一個點(x,y)嗽仪。

2.8.8 圓弧context. arc(x, y, radius, startAngle, endAngle, anticlockwise)

????方法調(diào)用格式:

context . arc(x, y, radius, startAngle,endAngle, anticlockwise)

????方法概述:

????????本方法先增加一條直線到子路徑列表荒勇,然后增加一個圓弧子路徑到子路徑列表。直線子路徑是由上一個點到圓弧子路徑的起始點闻坚,而圓弧則為按照給定的開始角度沽翔、結(jié)束角度和半徑描述的按照給定的方向[布爾類型,anticlockwise-逆時針(true)]圓弧上窿凤;假如半徑為負(fù)值仅偎,拋出INDEX_SIZE_ERR的異常;

????JS代碼:

context.beginPath();

context.moveTo(100,50);

context.arc(250,50,50,1.5708,3.14,true);

context.stroke();

注釋掉moveTo語句雳殊,則僅僅繪制圓弧:

2.8.9 最短圓弧context. arcTo(x1, y1, x2, y2, radius)

????方法調(diào)用格式:

context . arcTo(x1, y1, x2, y2, radius)

????方法概述:

????????本方法繪制出子路徑最后一個點(x0,y0)和(x1,y1)以及(x1,y1)和(x2,y2)構(gòu)成的兩條直線間半徑為radius的最短弧線橘沥,并用直線連接(x0,y0);假如半徑為負(fù)值夯秃,拋出INDEX_SIZE_ERR的異常座咆;

????????如圖所示,繪制曲線由1寝并,開始繪制箫措。

????????JS代碼如下:

context.beginPath();

context.moveTo(150,50);

context.arcTo(200,50,100,200,20);

context.arcTo(200,50,100,200,40);

context.arcTo(200,50,100,200,80);

context.arcTo(200,50,100,200,120);

context.arcTo(200,50,100,200,160);

context.stroke();

2.8.10 二次方腹备、三次方貝塞爾曲線

????????貝塞爾曲線的一般概念:在數(shù)學(xué)的數(shù)值分析領(lǐng)域中衬潦,貝賽爾曲線(Bezier curve)是電腦圖形學(xué)中相當(dāng)重要的參數(shù)曲線。更高維度的貝賽爾曲線被稱作貝塞爾曲面植酥。對于n階貝塞爾曲線可如下推斷镀岛,給定P0、P1友驮、P2…Pn漂羊,其貝賽爾曲線即為

????????用平常話說,n階的貝賽爾曲線就是雙n-1階貝賽爾曲線之間的插值卸留。

????????由公式可以得出二次方貝塞爾曲線公式如下:

????????TrueType字型就運用了以貝塞爾樣條組成的二次方貝賽爾曲線走越。


????方法調(diào)用格式:

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

quadraticCurveTo(cpx, cpy, x, y)

????方法概述:

????????上面分別是三次貝賽爾曲線和二次貝賽爾曲線的調(diào)用格式。其主要區(qū)別在于控制曲線的控制點式不一樣的耻瑟。其起始點均為子路徑的最后一個點旨指,結(jié)束點均為(x,y)赏酥;在最后均要把(x,y)點加入到子路徑中谆构。

????????其繪制圖形的例子如下裸扶,三次貝賽爾曲線有兩個紅點作為曲線平滑的控制點,而二次貝塞爾曲線僅有一個控制點搬素。

2.8.10.1 二次貝賽爾曲線quadraticCurveTo(cpx, cpy, x,y)


2.8.10.2 三次貝賽爾曲線bezierCurveTo(cp1x, cp1y, cp2x,cp2y, x, y)


2.9 文字

????????繪圖上下文提供了得到和設(shè)置文字樣式的接口方法呵晨。

2.9.1 context.font[=value]

????????獲得和設(shè)置文字設(shè)置: context.font[=value],可以參考CSS中對font風(fēng)格的設(shè)置。

2.9.2 context.textAlign[=value]

????????獲取或設(shè)置文字對齊方式:context.textAlign[=value]熬尺,取值如下:

start??????????????? 默認(rèn)值摸屠,與canvas風(fēng)格中的direction定義有關(guān)

end? ? ? ? ? ? ? ? ?與canvas風(fēng)格中的direction定義有關(guān)

left? ? ? ? ? ? ? ? ? 左

right??????????????? 右

center???????????? 居中


2.9.3 context.textBaseline

????????獲得和設(shè)置文字對齊基線:context.textBaseline[=value],value的取值如下:

2.9.4 context.fillText(text, x, y[,maxWidth])

????????繪制填充的文字,

2.9.5 context.strokeText(text, x, y[,maxWidth])

????????對文字進行描邊猪杭,不填充內(nèi)部區(qū)域餐塘。

2.9.6 context.measureText(text)

????????按照當(dāng)前字體對給定的文字進行測量:

metrics = context.measureText(text),該方法返回一個TextMetrics對象,可以調(diào)用對象的width屬性得到文字的寬度皂吮。

2.10 繪制圖片

2.10.1 drawImage方法

????????要在繪圖上下文中繪制圖片戒傻,可以使用drawImage方法。該方法有三種不同的參數(shù):

????????其中的image參數(shù)可以是HTMLImageElement蜂筹、HTMLCanvasElement和HTMLVideoElement中的任一個對象需纳。

????????繪制參數(shù)的含義可以參看下圖:

????異常:

????????如果第一個參數(shù)不是指定的元素類型,拋出一個TYPE_MISMATCH_ERR異常艺挪,如果圖片不能進行解碼不翩,則拋出INVALID_STATE_ERR異常,如果第二個參數(shù)不是允許的值麻裳,則拋出SYNTAX_ERR異常口蝠。????

????參數(shù)默認(rèn)值:

????????如果沒有指定dw和dh,則默認(rèn)等于sw和sh津坑,如果sx,sy,sw,sh均沒有提供妙蔗,則默認(rèn)為sx,xy=0,0;sw和sh為圖片的像素寬高疆瑰。

2.10.2 圖片調(diào)用方式

????????下面給出圖片的幾種調(diào)用方式:

????1.引用頁面內(nèi)圖片:

????????我們可以通過 document.images 集合眉反、document.getElementsByTagName方法又或者document.getElementById 方法來獲取頁面內(nèi)的圖片(如果已知圖片元素的 ID。

????2.引用canvas元素

????????用 document.getElementsByTagName 或document.getElementById 方法來獲取其它 canvas 元素穆役。但你引入的應(yīng)該是已經(jīng)準(zhǔn)備好的canvas寸五。一個常用的應(yīng)用就是為另一個大的 canvas 做縮略圖。

????3.創(chuàng)建圖像

????????我們可以用腳本創(chuàng)建一個新的 Image對象耿币,但這種方法的主要缺點是如果不希望腳本因為等待圖片裝置而暫停梳杏,還得需要突破預(yù)裝載。

var img = new Image(); // Create new Image

img.src = 'myImage.png'; // Set source path

????????當(dāng)腳本執(zhí)行后,圖片開始裝載十性。若調(diào)用 drawImage 時叭莫,圖片沒裝載完,腳本會等待直至裝載完畢烁试。如果不希望這樣雇初,可以使用onload 事件:

var img = new Image(); // Create new Image

img.onload = function(){

????// 執(zhí)行drawImage 語句

}

img.src = 'myImage.png'; // Set source path

????????如果你只用到一張圖片的話,這已經(jīng)夠了减响。但一旦需要不止一張圖片靖诗,那就需要更加復(fù)雜的處理方法,但圖片預(yù)裝載策略超出本規(guī)范的范圍支示。

????4.通過 data: url 方式嵌入圖像

????????我們還可以通過 data: url 方式來引用圖像刊橘。Data urls 允許用一串Base64 編碼的字符串的方式來定義一個圖片。其優(yōu)點就是圖片內(nèi)容即時可用颂鸿,無須再到服務(wù)器兜一圈促绵。(還有一個優(yōu)點是,可以將 CSS嘴纺,JavaScript败晴,HTML 和 圖片全部封裝在一起,遷移起來十分方便栽渴。)缺點就是圖像沒法緩存尖坤,圖片大的話內(nèi)嵌的url數(shù)據(jù)會相當(dāng)?shù)拈L,例如:

var img_src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAyCAYAAADLLVz8AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAALESURBVGhD7ZUxSFVhFMfvezi8wcFBSMjhRYNBQUEOQQ4ODYFBQmOLUVtCDQ1By4OGBoeKgkYTh4gGl6CCIByaLDIqKAo0KhIUEmoUX7//49zHh/Tgil4x+F/4c8533nfPPd/Pcz6zzI8JmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmIAJmEC5BCrlps+yZtas842FSlbp+K31bH0yraOaVc+VXdd25a9uV6Kt5AHuGO9/wM5KW8m10+9uqgPppl6kw+7loFNonvUwOoP/g/hd7B8dQvvQYdyXxB7lHUjsBBph/Rbdj71N7D7Wi7HuxY6jW8RW6dDL+M/pzPc5IHJ0Ry37iT1kXw3bozh2AE2x/0vZQAt3IIWpuDkKOo4+4a9xsJPYB6xnBQvdUcHEx/EncAX1YnJowb4X718KAK2f8bVuKAaMFexBdA2N8vN5Yh+TPLWoZUS5Iq7c0/hH0SB6Uja8TeUXFPQ5fYn1DBKo1l2H/xtbw77BXo34EL46TGAn0LQg6d5Dgq93m/g3c4Cxt5/YMlpAx9LvxvvL2K4EaoN97yJfn3IidXKpT+EOpIo9qN0FUZUKVJfpWaJLND4HkMYrH5/vyQkO4evQdfZ+Rc/y3/Bvo0Y+1oyf3tPIdqfdF/v7sIvE1zbQWdGa+FLEVU+pT2GAFPWaSnR/1ZOK5vFPq+vQKbQakJ9iz6pDFE/2C1hXgGrD+tcJk/F+jH9De7BH6DL9EV6RYxBfo/r/PDFmGjeN1QWNCHYOfUO/UAtWHPRnxCbzEd6wX2M+Fvs1bqmGYnwFSaOsq2E4rgzdc7oOrsfo69tXNP7YFznNyJf+sXcH6Ljj+tNqOt01xHs6dJf+m7fvr6Ini05P7z11/u6DVPRA3mcCJmACJmACJmACJmACJmACJmACJmACJmACJmACJmACJrBTBP4C/mNz5egh3WQAAAAASUVORK5CYII=';

????????有興趣的朋友可以使用<img src=’上述變量值’>的方法顯示出上面的圖片闲擦。

2.11 像素級操作(good)

????????2D Context API 提供了三個方法用于像素級操作:createImageData, getImageData, 和putImageData慢味。

????????ImageData對象保存了圖像像素值。每個對象有三個屬性: width, height 和data墅冷。data 屬性類型為CanvasPixelArray纯路,用于儲存width*height*4個像素值。每一個像素有RGB值和透明度alpha值(其值為 0 至255寞忿,包括alpha在內(nèi))驰唬。像素的順序從左至右,從上到下罐脊,按行存儲定嗓。

????????Canvas提供像素級數(shù)據(jù)蜕琴,為很多算法的應(yīng)用提供了平臺萍桌,實現(xiàn)photoshop中的眾多神奇圖像效果在前端都已成為可能。甚至于我們還能實現(xiàn)電影的藍(lán)幕效果——針對video的幀,通過drawImage繪進canvas凌简,再做rgba處理上炎,將規(guī)定顏色的像素的alpha值設(shè)為0,就能使特定部分變成透明,進而實現(xiàn)視頻合成藕施。查看演示

canvas的像素級操作——1.引子

http://cssass.com/blog/2012/1140.html

canvas的像素級操作——2.RGBA通道調(diào)色

http://cssass.com/blog/2012/1158.html

canvas的像素級操作——3.使用卷積矩陣

http://cssass.com/blog/2012/1165.html

canvas的像素級操作——4.關(guān)注性能

http://cssass.com/blog/2012/1179.html

[Color]彩色轉(zhuǎn)灰度算法徹底學(xué)習(xí)

http://www.cnblogs.com/zyl910/archive/2006/05/22/2186658.html

在HTML5 的CANVAS 中應(yīng)用卷積矩陣對圖像處理

http://shawphy.com/2011/08/convolution-matrix-in-canvas.html

2.11.1 createImageData方法

imagedata = context . createImageData(sw, sh)

imagedata = context . createImageData(imagedata)

????方法概述:

????????createImageData方法根據(jù)給定的CSS像素寬高或指定的imagedata具有的寬高建立一個ImageData對象寇损,該對象為透明黑。該方法具體實例化一個新的空ImageData對象裳食。

2.11.2 getImageData方法

imagedata = context . getImageData(sx,sy,sw, sh)

????方法概述:

????????getImageData方法根據(jù)給定的繪圖畫布矩形面積(sx,sy,sw,sh)矛市,生成畫布上該矩形面積的圖形內(nèi)容,并綜合為ImageData對象返回诲祸。畫布外的像素作為透明黑返回浊吏。

2.11.3 putImageData方法

imagedata = context . putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])

????方法概述:

????????在繪圖畫布上繪制給定的ImageData對象。假如臟矩形被提供救氯,則只有在臟矩形上面的像素被繪制找田。本方法對全局透明、陰影和全局組合屬性均忽略着憨。

????????異常:假如第一個參數(shù)不是ImageData對象墩衙,拋出TYPE_MISMATCH_ERR異常,假如任一數(shù)字參數(shù)是無窮或非數(shù)字甲抖,則拋出NOT_SUPPORTED_ERR錯誤漆改。

????????putImageData參數(shù)有(ImageData,dx, dy [, DirtyX] [, DirtyX] [, DirtyWidth] [, DirtyHeight])

????imageData:包含了圖像的width,height,還有一個CanvasPixelArray,前面已經(jīng)提了准谚。

????dx, dy:表示繪圖起始位置籽懦。相對于canvas區(qū)域左上角。

????????后面四個可選參數(shù):表示可見區(qū)范圍氛魁。相對于起繪點暮顺,即上面的參數(shù)dx,dy表示的點。缺省為0,0,ImageData.width,ImageData.height秀存。

2.11.3.1 具體用法

????????通過將源canvas中像素數(shù)據(jù)ImageData捶码,輸出(putImageData)到新的canvas中,達(dá)到復(fù)制作用或链。

<script type="text/javascript">

function draw(){

??????????? /*在canvas中繪制image*/

??????????? var canvas1 =document.getElementById("MyCanvas");

??????????? var ctx1 =canvas1.getContext("2d");

??????????????????????? ctx1.drawImage(imgObj,0,0);

}

function clone(){

??????????? /*在canvas2中繪制canvas1——普通復(fù)制*/

??????????? var origin =document.getElementById("MyCanvas");

??????????? var canvas2 =document.getElementById("YourCanvas");

??????????? var ctx2 =canvas2.getContext("2d");

? ? ? ? ? ? ctx2.drawImage(origin,0,0);//drawImage不僅可以繪image惫恼,也可以繪canvas對象,甚至還可以繪video的幀

}

function cloneData(canvasObj){

??????????? /*獲取canvas1中的ImageData澳盐,在canvas3中輸出 ——像素級復(fù)制*/

??????????? var origin =document.getElementById("MyCanvas");

??????????? var canvas3 =document.getElementById("GodCanvas");

??????????? var ctx3 =canvas3.getContext("2d");

??????????? var canvasCtx = origin.getContext("2d");

??????????? var imagePix = canvasCtx.getImageData(0,0,origin.width,origin.height); //獲取canvas1繪圖環(huán)境下的參數(shù)范圍內(nèi)的imageData祈纯。

? ? ? ? ? ? ctx3.putImageData(imagePix,0,0);??? //putImageData輸出圖像

}

/* 以下與示例代碼無關(guān)*/

function Load(canvas){

??????????? /* canvas Loading效果*/

??????????? var backCtx =canvas.getContext('2d');

??????????????????????? backWidth= canvas.width;

??????????????????????? backHeight= canvas.height;

??????????? var drawIntervalID,

??????????????????????? spokes= 7;

??????????? var????? drawPad =document.createElement('canvas');

??????????????????????? drawPad.width= 30;

??????????????????????? drawPad.height= 30;

??????????? var????? drawCtx = drawPad.getContext('2d');

??????????????????????? drawCtx.translate(drawPad.width/2,drawPad.height/2);

??????????????????????? drawCtx.lineWidth= 5;

??????????????????????? drawCtx.lineCap= "round";

??????????????????????? drawCtx.strokeStyle= "rgba(0,0,0,0.1)";

??????????????????????? drawCtx.fillStyle= "#fff";

??????????? var draw =function(){

??????????????????????? drawCtx.fillRect(0,0,drawPad.width ,drawPad.height);

??????????????????????? drawCtx.rotate(Math.PI*2/spokes);

??????????????????????? for(var i=0; i

??????????????????????????????????? drawCtx.rotate(Math.PI*2/spokes);

??????????????????????????????????? drawCtx.beginPath();

??????????????????????????????????? drawCtx.moveTo(0,8);

??????????????????????????????????? drawCtx.lineTo(0,10);

??????????????????????????????????? drawCtx.stroke();

??????????????????????? }

??????????????????????? backCtx.drawImage(drawPad,(backWidth- drawPad.width)/2, (backHeight - drawPad.height)/2);

??????????? }

??????????? this.loading =function(){

??????????????????????? ?drawIntervalID = setInterval(draw,200);

??????????? }

??????????? this.loaded =function(){

??????????????????????? clearInterval(drawIntervalID);

??????????????????????? backCtx.clearRect((backWidth- drawPad.width)/2, (backHeight - drawPad.height)/2, drawPad.width,drawPad.height);

??????????? }

}

var imgObj = document.getElementById("imgObj");

var canvas = document.getElementsByTagName('canvas');

for(var i = 0, l = canvas.length; i < l; i++ ){

??????????? var loadObj = newLoad(canvas[i]);

??????????? (function(obj){

??????????????????????? obj.loading();

??????????????????????? imgObj.addEventListener('load',obj.loaded,false);

??????????? })(loadObj);

}

imgObj.addEventListener('load',function(){

??????????? draw();

??????????? clone();

??????????? cloneData();

},false);

</script>

2.11.4 示例

????????下面展示了對一張圖片進行反色、透明的一個例子叼耙,從例子中可以看出腕窥,有了像素級的控制能力,我們可以很輕易的對原有圖片進行各種圖像濾鏡操作筛婉。圖示如下:

????????JS代碼:[當(dāng)你在word中選擇上面的圖片簇爆,會發(fā)現(xiàn)反色濾鏡常用在選擇操作里]

var imgSrc =? document.getElementById('codeex.cn')

context.drawImage(imgSrc,10,10);

var imgd =? context.getImageData(10,10,100,122);

var pix =? imgd.data;


//反色處理

for(var? i=0,n=pix.length;i

{

??? pix[i] = 255 - pix[i]; //紅

??? pix[i+1] = 255-pix[i+1]; //綠

??? pix[i+2] = 255-pix[i+2]; //藍(lán)

??? pix[i+3] = pix[i+3]; //alpha

}


context.putImageData(imgd,130,10);

imgd =? context.getImageData(10,10,100,122);

pix =? imgd.data;

//透明處理 透明度0.6

for(var? i=0,n=pix.length;i

{

??? pix[i] = pix[i]; //紅

??? pix[i+1] = pix[i+1]; //綠

??? pix[i+2] = pix[i+2]; //藍(lán)

??? pix[i+3] = pix[i+3]*0.6; //alpha

}

context.putImageData(imgd,260,10);

2.11.5 性能優(yōu)化示例

canvas像素級操作

http://blog.sina.com.cn/s/blog_502364000100qwc8.html

2.12 繪圖模型

????????在本文描述的畫布中繪圖,瀏覽器一般按照下面的順序進行繪制:

????1.準(zhǔn)備形狀或圖片,此時圖片假設(shè)為A入蛆,形狀必須被所有屬性描述的形狀响蓉,且經(jīng)過坐標(biāo)轉(zhuǎn)換;

????2.當(dāng)繪制陰影時哨毁,準(zhǔn)備圖片A枫甲,并繪制陰影,形成圖片B扼褪;

????3.當(dāng)繪制陰影時言秸,為B的每個像素乘上alpha值;

????4.當(dāng)繪制陰影時迎捺,則根據(jù)組合參數(shù)對B和本畫布剪貼區(qū)域內(nèi)的圖片進行組合举畸;

????5.在圖片A上每個像素乘上alpha值;

????6.在圖片A上根據(jù)組合參數(shù)對A和本畫布剪貼區(qū)域內(nèi)的圖片進行組合凳枝;

3 Canvas動畫庫——KineticJS

以下教程是根據(jù)2012年教程整理的抄沮,部分接口有調(diào)整,后續(xù)注意逐步整理更新

KineticJS中文系列教程

http://iysm.net/?paged=2

How It Works

https://github.com/ericdrowell/KineticJS/wiki

4 Canvas動畫庫——Collie

Collie——基于 HTML5 的高性能

JavaScript 動畫庫

http://www.cnblogs.com/lhb25/archive/2012/12/17/create-highly-optimized-animations-using-html5.html

5 Canvas動畫庫——EaselJS

EaselJS(CreateJS)屏幕適配

http://abellee.github.io/blog/easeljs/2014/07/11/EaselJS(CreateJS)%E5%B1%8F%E5%B9%95%E9%80%82%E9%85%8D.html

CreateJS基礎(chǔ)

http://www.jikexueyuan.com/course/276.html


6 特效合集

6.1 星星圖形

function drawStar(ctx,r){

??? ctx.save();

??? ctx.beginPath()

??? ctx.moveTo(r,0);

??? for (var i=0;i<9;i++){

??????? ctx.rotate(Math.PI/5);

??????? if(i%2 == 0) {

???????????ctx.lineTo((r/0.525731)*0.200811,0);

??????? } else {

??????????? ctx.lineTo(r,0);

??????? }

??? }

??? ctx.closePath();

??? ctx.fill();

??? ctx.restore();

}


7 參考鏈接

HTML5 canvas addColorStop() 方法

http://www.w3school.com.cn/tags/canvas_addcolorstop.asp

canvas像素級操作

http://blog.sina.com.cn/s/blog_502364000100qwc8.html


專欄——HTML5 Canvas編程

http://blog.csdn.net/column/details/canvas-programming.html


專欄——html5 Canvas畫圖系列教程目錄

http://jo2.org/html5-canvas-tutorial-list/


[Canvas系列]Canvas繪制圓弧形狀_04

http://blog.csdn.net/baihuaxiu123/article/details/53619435


HTML5 Canvas 畫圓教程

http://www.108js.com/article/article7/70206.html?id=1036


6.5 徑向漸變

http://www.lvyestudy.com/css3/css3_6.5.aspx

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岖瑰,一起剝皮案震驚了整個濱河市叛买,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蹋订,老刑警劉巖率挣,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異露戒,居然都是意外死亡椒功,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門智什,熙熙樓的掌柜王于貴愁眉苦臉地迎上來动漾,“玉大人,你說我怎么就攤上這事荠锭『得校” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵证九,是天一觀的道長删豺。 經(jīng)常有香客問我,道長愧怜,這世上最難降的妖魔是什么呀页? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮叫搁,結(jié)果婚禮上赔桌,老公的妹妹穿的比我還像新娘。我一直安慰自己渴逻,他們只是感情好疾党,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惨奕,像睡著了一般雪位。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梨撞,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天雹洗,我揣著相機與錄音,去河邊找鬼卧波。 笑死时肿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的港粱。 我是一名探鬼主播螃成,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼查坪!你這毒婦竟也來了寸宏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤偿曙,失蹤者是張志新(化名)和其女友劉穎氮凝,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體望忆,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡罩阵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了启摄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片永脓。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鞋仍,靈堂內(nèi)的尸體忽然破棺而出常摧,到底是詐尸還是另有隱情,我是刑警寧澤威创,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布落午,位于F島的核電站,受9級特大地震影響肚豺,放射性物質(zhì)發(fā)生泄漏溃斋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一吸申、第九天 我趴在偏房一處隱蔽的房頂上張望梗劫。 院中可真熱鬧享甸,春花似錦、人聲如沸梳侨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽走哺。三九已至蚯嫌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丙躏,已是汗流浹背择示。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晒旅,地道東北人栅盲。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像废恋,于是被迫代替她去往敵國和親剪菱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容