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

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();

//idmyimg的圖片元素

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中文系列教程

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

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)屏幕適配

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像素級(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 徑向漸變

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一:canvas簡(jiǎn)介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,874評(píng)論 2 32
  • 一、圖形的組合方式 globalAlpha是一個(gè)介于0和1之間的值(包括0和1),用于指定所有繪制的透明度。默認(rèn)值...
    空谷悠閱讀 1,471評(píng)論 0 0
  • 一、canvas簡(jiǎn)介 1.1 什么是canvas?(了解) 是HTML5提供的一種新標(biāo)簽 Canvas是一個(gè)矩形區(qū)...
    J_L_L閱讀 1,671評(píng)論 0 4
  • 啥是canvas? HTML5 標(biāo)簽用于繪制圖像(通過腳本,通常是 JavaScript)。不過, 元素本身...
    kiaizi閱讀 847評(píng)論 0 4
  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,331評(píng)論 3 23

友情鏈接更多精彩內(nèi)容