1 Canvas接口元素定義
1.1 getContext()方法
????????為了在canvas上繪制,你必須先得到一個(gè)畫布上下文對(duì)象的引用,用本方法即可完成這一操作,格式如下:
context = canvas . getContext(contextId)
????????方法返回一個(gè)指定contextId的上下文對(duì)象,如果指定的id不被支持,則返回null,當(dāng)前唯一被強(qiáng)制必須支持的是“2d”,也許在將來會(huì)有“3d”,注意,指定的id是大小寫敏感的。
1.2 toDataURL()方法
????????返回一張使用canvas繪制的圖片,返回值符合data:URL格式,格式如下:
url = canvas . toDataURL( [ type, ... ])
????????規(guī)范規(guī)定,在未指定返回圖片類型時(shí),返回的圖片格式必須為PNG格式,如果canvas沒有任何像素,則返回值為:“data:,”,這是最短的data:URL,在text/plain資源中表現(xiàn)為空字符串。type的可以在image/png,image/jpeg,image/svg+xml等 MIME類型中選擇。如果是image/jpeg,可以有第二個(gè)參數(shù),如果第二個(gè)參數(shù)的值在0-1之間,則表示JPEG的質(zhì)量等級(jí),否則使用瀏覽器內(nèi)置默認(rèn)質(zhì)量等級(jí)。
????????下面的代碼可以從ID為codeex的canvas中取得繪制內(nèi)容,并作為DataURL傳遞給img元素,并顯示。
var canvas =? document.getElementById('codeex');
var url = canvas.toDataURL();
//id為myimg的圖片元素
myimg.src = url;
2 二維繪圖上下文
????????當(dāng)使用一個(gè)canvas元素的getContext(“2d”)方法時(shí),返回的是CanvasRenderingContext2D對(duì)象,其內(nèi)部表現(xiàn)為笛卡爾平面坐標(biāo),并且左上角坐標(biāo)為(0,0),在本平面中往右則x坐標(biāo)增加和往下方y(tǒng)坐標(biāo)增加。每一個(gè)canvas元素僅有一個(gè)上下文對(duì)象。其接口如下:
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)
??? 每個(gè)上下文都包含一個(gè)繪圖狀態(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)用的所有樣式和變形的一個(gè)快照。而狀態(tài)的應(yīng)用則可以避免繪圖代碼的過度膨脹。
2.1.1 context . restore()
2.1.2 context . save()
2.2 轉(zhuǎn)換(Transformations)
? ? ? ? 當(dāng)建立形狀和路徑時(shí),轉(zhuǎn)換矩陣被應(yīng)用到其坐標(biāo)上。轉(zhuǎn)換的執(zhí)行順序是嚴(yán)格按順序的(注:原文是反向,經(jīng)試驗(yàn)應(yīng)該是按調(diào)用順序的)。
????????在做轉(zhuǎn)換/變形之前先保存狀態(tài)是一個(gè)良好的習(xí)慣。大多數(shù)情況下,調(diào)用restore 方法比手動(dòng)恢復(fù)原先的狀態(tài)要簡(jiǎn)單得多。
2.2.1 context . rotate(angle)
context . rotate(angle) //按給定的弧度旋轉(zhuǎn),按順時(shí)針旋轉(zhuǎn)
rotate方法旋轉(zhuǎn)的中心始終是canvas的原點(diǎn),如果要改變它,需要使用translate方法。

2.2.2 context .scale(x, y)
????????context . scale(x, y) //按給定的縮放倍率縮放,1.0,為不變,參數(shù)比1.0小表示縮小,否則表示放大。默認(rèn)情況下,canvas的1 單位就是1 個(gè)像素。舉例說,如果我們?cè)O(shè)置縮放因子是0.5,1個(gè)單位就變成對(duì)應(yīng)0.5 個(gè)像素,這樣繪制出來的形狀就會(huì)是原先的一半。同理,設(shè)置為2.0 時(shí),1個(gè)單位就對(duì)應(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方向偏移指定的量,其用來移動(dòng)Canvas的原點(diǎn)到一個(gè)指定的值
2.2.5.1 示例
????????下面是一個(gè)利用translate方法進(jìn)行繪制螺旋圖案的例子:

//繪制螺旋圖案的函數(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對(duì)象,非法的值將被忽略。
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) //在給定偏移的地方增加一個(gè)漸變顏色點(diǎn),偏移量取值范圍為0-1.0之間,否則產(chǎn)生一個(gè)INDEX_SIZE_ERR的異常,color為DOM字符串,如果不能解析,則拋出一個(gè)SYNTAX_ERR的異常。
2.4.4 context . createLinearGradient(x0, y0, x1, y1)
gradient = context . createLinearGradient(x0, y0, x1, y1) //建立一個(gè)線性漸變,如果任何一個(gè)參數(shù)不是有限值,則拋出一個(gè)NOT_SUPPORTED_ERR的異常。
2.4.4.1 addColorStop()
? ??定義和用法
????????addColorStop()方法規(guī)定 gradient 對(duì)象中的顏色和位置。
????????addColorStop()方法與 createLinearGradient() 或 createRadialGradient() 一起使用。
? ??????注釋:您可以多次調(diào)用addColorStop() 方法來改變漸變。如果您不對(duì) gradient 對(duì)象使用該方法,那么漸變將不可見。為了獲得可見的漸變,您需要?jiǎng)?chuàng)建至少一個(gè)色標(biāo)。
? ??JavaScript語(yǔ)法:? ??
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 示例——通過多個(gè)addColorStop() 方法來定義漸變
????????通過多個(gè) 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) //建立一個(gè)徑向漸變,如果任何一個(gè)參數(shù)不是有限值,則拋出一個(gè)NOT_SUPPORTED_ERR的異常。假如r0或r1為負(fù)值,則拋出INDEX_SIZE_ERR的異常。
2.4.5.1 繪制過程
????????createRadialGradient(x0,y0,r0,x1,y1,r1)方法有六個(gè)參數(shù),前三個(gè)參數(shù)表示開始的圓,其圓點(diǎn)在(x0,y0),半徑為r0,后三個(gè)表示結(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))為圓點(diǎn),r(w)為半徑的圓周上所有點(diǎn)的顏色均為Color(w)。
????3. 對(duì)于任意的w取值(-∞ -- +∞),確保r(w)>0,總是可以知道畫布中已知點(diǎn)的顏色。
????????言而總之:這個(gè)效果就是建立一個(gè)圓錐體(手電筒效果)渲染效果,圓錐體的開始圓使用開始顏色偏移量為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)格還有圖案對(duì)象:CanvasPattern,其調(diào)用格式如下:
pattern = context . createPattern(image, repetition)
????????本方法用指定的圖像和重復(fù)方向建立一個(gè)畫布圖案對(duì)象,image參數(shù)可以為img,canvas,video元素中的任一個(gè),如果不滿足此條件,則拋出TYPE_MISMATCH_ERR異常,如果圖片編碼未知或沒有圖像數(shù)據(jù),則拋出INVALID_STATE_ERR異常;第二個(gè)參數(shù)可以是下列值:
????repeat????默認(rèn)參數(shù),如果為空,則為此參數(shù),表示兩個(gè)方向重復(fù)
????repeat-x????僅水平重復(fù)
????repeat-y????僅垂直重復(fù)
????no-repeat????不重復(fù)
????????如果image參數(shù)是一個(gè)HTMLImageElement對(duì)象,但對(duì)象的complete屬性是false,則執(zhí)行時(shí)拋出INVLAID_STATE_ERR異常;
????????如果image參數(shù)是一個(gè)HTMLVideoElement對(duì)象,但其readyState屬性是HAVE_NOTHING或HAVE_METADATA,則執(zhí)行時(shí)拋出拋出INVLAID_STATE_ERR異常;
????????如果image參數(shù)是一個(gè)HTMLCanvasElement對(duì)象,但其width屬性或height屬性是0,則執(zhí)行時(shí)拋出拋出INVLAID_STATE_ERR異常。
????????圖案的繪制時(shí)從左上角開始的,根據(jù)不同的參數(shù)進(jìn)行重復(fù)繪制。如果傳遞的圖片是動(dòng)畫,則選取海報(bào)或第一幀作為其繪制圖案源,如果使用HTMLVideoElement為對(duì)象,則當(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個(gè),格式如下:
context . lineCap [ = value ] //返回或設(shè)置線段的箭頭樣式,僅有三個(gè)選項(xiàng):butt(默認(rèn)值),round,square;其他值忽略


2.5.2 context . lineJoin
context . lineJoin [ = value ] ///返回或設(shè)置線段的連接方式,僅有三個(gè)選項(xiàng):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)確,請(qǐng)參看英文部分
2.5.5 線寬
????????線寬是指給定路徑的中心到兩邊的粗細(xì)。換句話說就是在路徑的兩邊各繪制線寬的一半。因?yàn)楫嫴嫉淖鴺?biāo)并不和像素直接對(duì)應(yīng),當(dāng)需要獲得精確的水平或垂直線的時(shí)候要特別注意。
????????想要獲得精確的線條,必須對(duì)線條是如何描繪出來的有所理解。見下圖,用網(wǎng)格來代表canvas 的坐標(biāo)格,每一格對(duì)應(yīng)屏幕上一個(gè)像素點(diǎn)。在第一個(gè)圖中,填充了 (2,1) 至 (5,5) 的矩形,整個(gè)區(qū)域的邊界剛好落在像素邊緣上,這樣就可以得到的矩形有著清晰的邊緣。

????????如果你想要繪制一條從 (3,1) 到 (3,5),寬度是 1.0的線條,你會(huì)得到像第二幅圖一樣的結(jié)果。實(shí)際填充區(qū)域(深藍(lán)色部分)僅僅延伸至路徑兩旁各一半像素。而這半個(gè)像素又會(huì)以近似的方式進(jìn)行渲染,這意味著那些像素只是部分著色,結(jié)果就是以實(shí)際筆觸顏色一半色調(diào)的顏色來填充整個(gè)區(qū)域(淺藍(lán)和深藍(lán)的部分)。
????????要解決這個(gè)問題,你必須對(duì)路徑施以更加精確的控制。已知粗 1.0 的線條會(huì)在路徑兩邊各延伸半像素,那么像第三幅圖那樣繪制從(3.5,1) 到 (3.5,5) 的線條,其邊緣正好落在像素邊界,填充出來就是準(zhǔn)確的寬為1.0 的線條。
????????對(duì)于那些寬度為偶數(shù)的線條,每一邊的像素?cái)?shù)都是整數(shù),那么你想要其路徑是落在像素點(diǎn)之間(如那從(3,1) 到 (3,5)) 而不是在像素點(diǎn)的中間。如果不是的話,端點(diǎn)上同樣會(huì)出現(xiàn)半渲染的像素點(diǎn)。
2.6 陰影(Shadows)
????????有關(guān)陰影的四個(gè)全局屬性將影響所有的繪畫操作。有關(guān)定義如下:
context . shadowBlur [ = value ] //返回或設(shè)置陰影模糊等級(jí),非大于等于0的值被忽略;
context . shadowColor [ = value ] //返回或設(shè)置陰影顏色
context . shadowOffsetX [ = value ]
context . shadowOffsetY [ = value ] //返回或設(shè)置陰影的偏移量
????????注意:上面的值均不受坐標(biāo)轉(zhuǎn)換的影響,可以看做是絕對(duì)值。
????????在上面的例子中增加下列語(yǔ)句,可以得到設(shè)置陰影的圖像:
context.shadowBlur=7;
context.shadowColor='rgb(200,0,0)';
context.shadowOffsetX = 3;
context.shadowOffsetY=3;

2.7 簡(jiǎn)單形狀(矩形)
????????形狀的繪制不影響當(dāng)前路徑(path),形狀是剪切區(qū)域的主題,也是陰影(Shadow)效果,全局透明(alpha),全局組合(composition)操作等的主題。其由下面三個(gè)方法來進(jìn)行簡(jiǎn)單的操作:
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)格,繪制一個(gè)盒子區(qū)域,影響其繪制風(fēng)格的有:strokeStyle,lineWidth,lineJoin,miterLimit(可能)。
2.8 復(fù)雜形狀(路徑-paths)
????????繪圖上下文總有一個(gè)當(dāng)前路徑,并且是僅此一個(gè),它不是繪圖狀態(tài)的一部分。
????????一個(gè)路徑有0個(gè)或多個(gè)子路徑列表。每個(gè)子路徑包含一個(gè)或多個(gè)點(diǎn)列表(這些點(diǎn)組成直的或彎曲的線段),和一個(gè)標(biāo)識(shí)子路徑是否閉合的標(biāo)志。少于兩個(gè)點(diǎn)的子路徑在繪圖時(shí)被忽略。操作這些形狀的方法稍微多些,如下所示:
????????默認(rèn)情況下,圖形上下文的路徑有0個(gè)子路徑。
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方法在繪圖上下文如果沒有子路徑時(shí),什么也不做;否則,它先把最后一個(gè)子路徑標(biāo)示為閉合,然后建立一個(gè)包含最后子路徑的第一個(gè)點(diǎn)的子路徑,并加入到繪圖上下文。有點(diǎn)拗口,其一般可以看為,假如最后一個(gè)子路徑,我們命名為spN,假設(shè)spN有多個(gè)點(diǎn),則用直線連接spN的最后一個(gè)點(diǎn)和第一個(gè)點(diǎn),然后關(guān)閉此路徑和moveTo到第一個(gè)點(diǎn)。
2.8.2 繪制函數(shù)
????????調(diào)用格式:
context . stroke()
context . fill()
context . clip()
????????方法概述:
2.8.2.1 context. stroke()
????????stroke方法使用lineWidth,lineCap,lineJoin,以及strokeStyle對(duì)所有的子路徑進(jìn)行填充。
2.8.2.2 context. fill()
????????fill方法使用fillStyle方式填充子路徑,未閉合的子路徑在填充式按照閉合方式填充,但并不影響實(shí)際的子路徑集合。
2.8.2.3 context. clip()
????????clip方法使用計(jì)算所有的子路徑而建立新的剪切區(qū)域,未閉合的子路徑在填充式按照閉合方式填充,但并不影響實(shí)際的子路徑集合,新的剪切區(qū)域?qū)⑻鎿Q當(dāng)前的剪切區(qū)域。
2.8.3 剪切(clip)
????????裁切路徑和普通的 canvas 圖形差不多,不同的是它的作用是遮罩,用來隱藏沒有遮罩的部分。如下圖所示。紅邊五角星就是裁切路徑,所有在路徑以外的部分都不會(huì)在canvas 上繪制出來。

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

????????首先,我畫了一個(gè)與 canvas 一樣大小的黑色方形作為背景,然后移動(dòng)原點(diǎn)至中心點(diǎn)。然后用 clip方法創(chuàng)建一個(gè)弧形的裁切路徑。裁切路徑也屬于 canvas 狀態(tài)的一部分,可以被保存起來。如果我們?cè)趧?chuàng)建新裁切路徑時(shí)想保留原來的裁切路徑,我們需要做的就是保存一下canvas 的狀態(tài)。
????????裁切路徑創(chuàng)建之后所有出現(xiàn)在它里面的東西才會(huì)畫出來。在畫線性漸變時(shí)這個(gè)就更加明顯了。然后在隨機(jī)位置繪制50 大小不一(經(jīng)過縮放)的顆,當(dāng)然也只有在裁切路徑里面的星星才會(huì)繪制出來。
????????代碼如下:
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)
????方法概述:
????????建立新的子路徑,并制定其第一個(gè)點(diǎn)為(x,y)。
2.8.6 lineTo方法
????調(diào)用格式:
context . lineTo(x, y)
????方法概述:
????????如果繪圖上下文沒有子路徑,則其等同于moveTo(x,y),否則,其建立一條在子路徑最后一個(gè)點(diǎn)到給定點(diǎn)的直線,并增加(x,y)到子路徑中。
2.8.7 rect方法
????調(diào)用格式:
context . rect(x, y, w, h)
????方法概述:
????????本方法建立二個(gè)新的子路徑,第一個(gè)子路徑包含四個(gè)點(diǎn):(x,y),(x+w,y),(x+w,y+h),(x,y+h),四個(gè)點(diǎn)的連接方式為直線,該子路徑被標(biāo)示為閉合路徑;最后再增加一個(gè)子路徑,其僅有一個(gè)點(diǎn)(x,y)。

2.8.8 圓弧context. arc(x, y, radius, startAngle, endAngle, anticlockwise)
????方法調(diào)用格式:
context . arc(x, y, radius, startAngle,endAngle, anticlockwise)
????方法概述:
????????本方法先增加一條直線到子路徑列表,然后增加一個(gè)圓弧子路徑到子路徑列表。直線子路徑是由上一個(gè)點(diǎn)到圓弧子路徑的起始點(diǎn),而圓弧則為按照給定的開始角度、結(jié)束角度和半徑描述的按照給定的方向[布爾類型,anticlockwise-逆時(shí)針(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語(yǔ)句,則僅僅繪制圓弧:

2.8.9 最短圓弧context. arcTo(x1, y1, x2, y2, radius)
????方法調(diào)用格式:
context . arcTo(x1, y1, x2, y2, radius)
????方法概述:
????????本方法繪制出子路徑最后一個(gè)點(diǎn)(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ù)曲線。更高維度的貝賽爾曲線被稱作貝塞爾曲面。對(duì)于n階貝塞爾曲線可如下推斷,給定P0、P1、P2…Pn,其貝賽爾曲線即為

????????用平常話說,n階的貝賽爾曲線就是雙n-1階貝賽爾曲線之間的插值。
????????由公式可以得出二次方貝塞爾曲線公式如下:

????????TrueType字型就運(yùn)用了以貝塞爾樣條組成的二次方貝賽爾曲線。
????方法調(diào)用格式:
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
quadraticCurveTo(cpx, cpy, x, y)
????方法概述:
????????上面分別是三次貝賽爾曲線和二次貝賽爾曲線的調(diào)用格式。其主要區(qū)別在于控制曲線的控制點(diǎn)式不一樣的。其起始點(diǎn)均為子路徑的最后一個(gè)點(diǎn),結(jié)束點(diǎn)均為(x,y);在最后均要把(x,y)點(diǎn)加入到子路徑中。
????????其繪制圖形的例子如下,三次貝賽爾曲線有兩個(gè)紅點(diǎn)作為曲線平滑的控制點(diǎn),而二次貝塞爾曲線僅有一個(gè)控制點(diǎn)。

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中對(duì)font風(fēng)格的設(shè)置。
2.9.2 context.textAlign[=value]
????????獲取或設(shè)置文字對(duì)齊方式: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è)置文字對(duì)齊基線:context.textBaseline[=value],value的取值如下:

2.9.4 context.fillText(text, x, y[,maxWidth])
????????繪制填充的文字,
2.9.5 context.strokeText(text, x, y[,maxWidth])
????????對(duì)文字進(jìn)行描邊,不填充內(nèi)部區(qū)域。
2.9.6 context.measureText(text)
????????按照當(dāng)前字體對(duì)給定的文字進(jìn)行測(cè)量:
metrics = context.measureText(text),該方法返回一個(gè)TextMetrics對(duì)象,可以調(diào)用對(duì)象的width屬性得到文字的寬度。
2.10 繪制圖片
2.10.1 drawImage方法
????????要在繪圖上下文中繪制圖片,可以使用drawImage方法。該方法有三種不同的參數(shù):

????????其中的image參數(shù)可以是HTMLImageElement、HTMLCanvasElement和HTMLVideoElement中的任一個(gè)對(duì)象。
????????繪制參數(shù)的含義可以參看下圖:

????異常:
????????如果第一個(gè)參數(shù)不是指定的元素類型,拋出一個(gè)TYPE_MISMATCH_ERR異常,如果圖片不能進(jìn)行解碼,則拋出INVALID_STATE_ERR異常,如果第二個(gè)參數(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.引用頁(yè)面內(nèi)圖片:
????????我們可以通過 document.images 集合、document.getElementsByTagName方法又或者document.getElementById 方法來獲取頁(yè)面內(nèi)的圖片(如果已知圖片元素的 ID。
????2.引用canvas元素
????????用 document.getElementsByTagName 或document.getElementById 方法來獲取其它 canvas 元素。但你引入的應(yīng)該是已經(jīng)準(zhǔn)備好的canvas。一個(gè)常用的應(yīng)用就是為另一個(gè)大的 canvas 做縮略圖。
????3.創(chuàng)建圖像
????????我們可以用腳本創(chuàng)建一個(gè)新的 Image對(duì)象,但這種方法的主要缺點(diǎn)是如果不希望腳本因?yàn)榈却龍D片裝置而暫停,還得需要突破預(yù)裝載。
var img = new Image(); // Create new Image
img.src = 'myImage.png'; // Set source path
????????當(dāng)腳本執(zhí)行后,圖片開始裝載。若調(diào)用 drawImage 時(shí),圖片沒裝載完,腳本會(huì)等待直至裝載完畢。如果不希望這樣,可以使用onload 事件:
var img = new Image(); // Create new Image
img.onload = function(){
????// 執(zhí)行drawImage 語(yǔ)句
}
img.src = 'myImage.png'; // Set source path
????????如果你只用到一張圖片的話,這已經(jīng)夠了。但一旦需要不止一張圖片,那就需要更加復(fù)雜的處理方法,但圖片預(yù)裝載策略超出本規(guī)范的范圍。
????4.通過 data: url 方式嵌入圖像
????????我們還可以通過 data: url 方式來引用圖像。Data urls 允許用一串Base64 編碼的字符串的方式來定義一個(gè)圖片。其優(yōu)點(diǎn)就是圖片內(nèi)容即時(shí)可用,無須再到服務(wù)器兜一圈。(還有一個(gè)優(yōu)點(diǎn)是,可以將 CSS,JavaScript,HTML 和 圖片全部封裝在一起,遷移起來十分方便。)缺點(diǎn)就是圖像沒法緩存,圖片大的話內(nèi)嵌的url數(shù)據(jù)會(huì)相當(dāng)?shù)拈L(zhǎng),例如:
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 像素級(jí)操作(good)
????????2D Context API 提供了三個(gè)方法用于像素級(jí)操作:createImageData, getImageData, 和putImageData。
????????ImageData對(duì)象保存了圖像像素值。每個(gè)對(duì)象有三個(gè)屬性: width, height 和data。data 屬性類型為CanvasPixelArray,用于儲(chǔ)存width*height*4個(gè)像素值。每一個(gè)像素有RGB值和透明度alpha值(其值為 0 至255,包括alpha在內(nèi))。像素的順序從左至右,從上到下,按行存儲(chǔ)。
????????Canvas提供像素級(jí)數(shù)據(jù),為很多算法的應(yīng)用提供了平臺(tái),實(shí)現(xiàn)photoshop中的眾多神奇圖像效果在前端都已成為可能。甚至于我們還能實(shí)現(xiàn)電影的藍(lán)幕效果——針對(duì)video的幀,通過drawImage繪進(jìn)canvas,再做rgba處理,將規(guī)定顏色的像素的alpha值設(shè)為0,就能使特定部分變成透明,進(jìn)而實(shí)現(xiàn)視頻合成。查看演示
canvas的像素級(jí)操作——1.引子
http://cssass.com/blog/2012/1140.html
canvas的像素級(jí)操作——2.RGBA通道調(diào)色
http://cssass.com/blog/2012/1158.html
canvas的像素級(jí)操作——3.使用卷積矩陣
http://cssass.com/blog/2012/1165.html
canvas的像素級(jí)操作——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)用卷積矩陣對(duì)圖像處理
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具有的寬高建立一個(gè)ImageData對(duì)象,該對(duì)象為透明黑。該方法具體實(shí)例化一個(gè)新的空ImageData對(duì)象。
2.11.2 getImageData方法
imagedata = context . getImageData(sx,sy,sw, sh)
????方法概述:
????????getImageData方法根據(jù)給定的繪圖畫布矩形面積(sx,sy,sw,sh),生成畫布上該矩形面積的圖形內(nèi)容,并綜合為ImageData對(duì)象返回。畫布外的像素作為透明黑返回。
2.11.3 putImageData方法
imagedata = context . putImageData(imagedata, dx, dy [, dirtyX, dirtyY, dirtyWidth, dirtyHeight ])
????方法概述:
????????在繪圖畫布上繪制給定的ImageData對(duì)象。假如臟矩形被提供,則只有在臟矩形上面的像素被繪制。本方法對(duì)全局透明、陰影和全局組合屬性均忽略。
????????異常:假如第一個(gè)參數(shù)不是ImageData對(duì)象,拋出TYPE_MISMATCH_ERR異常,假如任一數(shù)字參數(shù)是無窮或非數(shù)字,則拋出NOT_SUPPORTED_ERR錯(cuò)誤。
????????putImageData參數(shù)有(ImageData,dx, dy [, DirtyX] [, DirtyX] [, DirtyWidth] [, DirtyHeight])
????imageData:包含了圖像的width,height,還有一個(gè)CanvasPixelArray,前面已經(jīng)提了。
????dx, dy:表示繪圖起始位置。相對(duì)于canvas區(qū)域左上角。
????????后面四個(gè)可選參數(shù):表示可見區(qū)范圍。相對(duì)于起繪點(diǎn),即上面的參數(shù)dx,dy表示的點(diǎn)。缺省為0,0,ImageData.width,ImageData.height。
2.11.3.1 具體用法
????????通過將源canvas中像素?cái)?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對(duì)象,甚至還可以繪video的幀
}
function cloneData(canvasObj){
??????????? /*獲取canvas1中的ImageData,在canvas3中輸出 ——像素級(jí)復(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 示例
????????下面展示了對(duì)一張圖片進(jìn)行反色、透明的一個(gè)例子,從例子中可以看出,有了像素級(jí)的控制能力,我們可以很輕易的對(duì)原有圖片進(jìn)行各種圖像濾鏡操作。圖示如下:

????????JS代碼:[當(dāng)你在word中選擇上面的圖片,會(huì)發(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像素級(jí)操作
http://blog.sina.com.cn/s/blog_502364000100qwc8.html
2.12 繪圖模型
????????在本文描述的畫布中繪圖,瀏覽器一般按照下面的順序進(jìn)行繪制:
????1.準(zhǔn)備形狀或圖片,此時(shí)圖片假設(shè)為A,形狀必須被所有屬性描述的形狀,且經(jīng)過坐標(biāo)轉(zhuǎn)換;
????2.當(dāng)繪制陰影時(shí),準(zhǔn)備圖片A,并繪制陰影,形成圖片B;
????3.當(dāng)繪制陰影時(shí),為B的每個(gè)像素乘上alpha值;
????4.當(dāng)繪制陰影時(shí),則根據(jù)組合參數(shù)對(duì)B和本畫布剪貼區(qū)域內(nèi)的圖片進(jìn)行組合;
????5.在圖片A上每個(gè)像素乘上alpha值;
????6.在圖片A上根據(jù)組合參數(shù)對(duì)A和本畫布剪貼區(qū)域內(nèi)的圖片進(jìn)行組合;
3 Canvas動(dòng)畫庫(kù)——KineticJS
以下教程是根據(jù)2012年教程整理的,部分接口有調(diào)整,后續(xù)注意逐步整理更新
KineticJS中文系列教程
How It Works
https://github.com/ericdrowell/KineticJS/wiki
4 Canvas動(dòng)畫庫(kù)——Collie
Collie——基于 HTML5 的高性能
JavaScript 動(dòng)畫庫(kù)
http://www.cnblogs.com/lhb25/archive/2012/12/17/create-highly-optimized-animations-using-html5.html
5 Canvas動(dòng)畫庫(kù)——EaselJS
EaselJS(CreateJS)屏幕適配
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像素級(jí)操作
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 徑向漸變