html5 canvas api

W3C Canvas 2D API 规范 1.0 by codeEx.cn

Canvas 2D API 规范 1.0

(W3C Editor's Draft 21 October 2009)

翻译:CodeEx.CN2010/10/21

引用本文,请不要删掉翻译行,更多精彩,请访问:www.codeex.cn

原文请参看:

http://dev.w3.org/html5/canvas-api/canvas-2d-api.html

摘要................................................................2

1 介绍..........................................................2

1.1 术语:........................................................2

2 CANVAS接口元素定义............................................3

2.1 GETCONTEXT()方法..............................................3

2.2 TODATAURL()方法...............................................3

3 二维绘图上下文................................................4

3.1 CANVAS的状态..................................................7

3.2 转换(TRANSFORMATIONS).........................................8

3.3 合成(COMPOSITING)..........................................10

3.4 颜色和风格...................................................12

3.5 线风格.......................................................16

3.6 阴影(SHADOWS)................................................18

3.7 简单形状(矩形).............................................18

3.8 复杂形状(路径-PATHS).........................................19

3.8.1 路径起始函数................................................19

3.8.2 绘制函数....................................................19

3.8.3 辅助方法—点是否在路径里....................................22

3.8.4 MOVETO方法..................................................22

第 1 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

3.8.5 LINETO方法..................................................22

3.8.6 RECT方法....................................................22

3.8.7 圆弧........................................................23

3.8.8 最短圆弧....................................................24

3.8.9 二次方、三次方贝塞尔曲线....................................24

3.9 文字.........................................................25

3.10 绘制图片....................................................26

3.11 像素级操作..................................................27

3.11.1 CREATEIMAGEDATA方法.........................................28

3.11.2 GETIMAGEDATA方法............................................28

3.11.3 PUTIMAGEDATA方法............................................28

3.11.4 演示例子..................................................28

3.12 绘图模型【此段翻译不怎么样,可以参看原英文】................29

4 参考资料.....................................................29



摘要

本规范定义了二维Canvas(画布)的绘画API,使用这些API使得可以在Web页面上进行立即模式的二维图形绘制。

1

介绍

本规范描述了立即模式的API和为了在光栅风格的绘图区域内绘制2维矢量图形所必须的方法。其主要应用是HTML5规范定义的canvas元素。

1.1

术语:

2D:二维,你们懂的

3D:三维,你们懂的

API:编程接口

Canvas interface element:实现了本规范定义的绘图方法和属性的元素,简言之,就是“canvas”元素

Drawing context:绘图上下文,一个左上角为(0,0)的笛卡尔坐标平面,在本平面中往右则x坐标增加和往下方y坐标增加

Immediate-mode:立即模式,一种绘图格式,当绘制完成后,所有的绘图结构将从内存中立即丢弃,本API即为此种图形绘制格式

第 2 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

Retained-mode:残留模式:另一种绘图格式,当绘制完成后,所有的绘图结构仍在内存中残留,例如DOM、SVG即是此种绘制格式

Raster:光栅风格,图形的一种风格,其由多行断开的图片(行)组成,每行都包含确定的像素个数

Vector:矢量,你们懂的

source-over operator :我不懂,你们自己看吧

2

Canvas接口元素定义

DOM接口:

interface CanvasElement : Element {

attribute unsigned long width;

attribute unsigned long height;

Object getContext(in DOMString contextId);

DOMString toDataURL(optional in DOMString type, in any... args);

};

这里width和height必须是非负值,并且无论什么时候重新设置了width或height的值,画布中任何已绘对象都将被清除,如下所示的JS代码中,仅仅最后一个矩形被绘制:

// canvas is a reference to a <canvas> element

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

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

canvas.setAttribute('width', '300'); // clears the canvas

context.fillRect(0,100,50,50);

canvas.width = canvas.width; // clears the canvas

context.fillRect(100,0,50,50); // only this square remains

2.1

getContext()方法

为了在canvas上绘制,你必须先得到一个画布上下文对象的引用,用本方法即可完成这一操作,格式如下:

context = canvas . getContext(contextId)

方法返回一个指定contextId的上下文对象,如果指定的id不被支持,则返回null,当前唯一被强制必须支持的是“2d”,也许在将来会有“3d”,注意,指定的id是大小写敏感的。

2.2

toDataURL()方法

此函数,返回一张使用canvas绘制的图片,返回值符合data:URL格式,格式如下:

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

规范规定,在未指定返回图片类型时,返回的图片格式必须为PNG格式,

第 3 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

如果canvas没有任何像素,则返回值为:“data:,”,这是最短的data:URL,在text/plain资源中表现为空字符串。type的可以在image/png,image/jpeg,image/svg+xml等 MIME类型中选择。如果是image/jpeg,可以有第二个参数,如果第二个参数的值在0-1之间,则表示JPEG的质量等级,否则使用浏览器内置默认质量等级。

下面的代码可以从ID为codeex的canvas中取得绘制内容,并作为DataURL传递给img元素,并显示。

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

var url = canvas.toDataURL();

//id为myimg的图片元素

myimg.src = url;

3

二维绘图上下文

当使用一个canvas元素的getContext(“2d”)方法时,返回的是CanvasRenderingContext2D对象,其内部表现为笛卡尔平面坐标,并且左上角坐标为(0,0),在本平面中往右则x坐标增加和往下方y坐标增加。每一个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, infloat m22, in float dx, in float dy);

void transform(in float m11, in float m12, in float m21, in floatm22, 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)

第 4 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

attribute any strokeStyle; // (default black)

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

CanvasGradient createRadialGradient(in float x0, in float y0, infloat 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);

第 5 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

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, optionalin float maxWidth);

TextMetrics measureText(in DOMString text);

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

// drawing images

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

void drawImage(in HTMLImageElement image, in float sx, in floatsy, in float sw, in float sh, in float dx, in float dy, in floatdw, in float dh);

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

void drawImage(in HTMLCanvasElement image, in float sx, in floatsy, in float sw, in float sh, in float dx, in float dy, in floatdw, in float dh);

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

void drawImage(in HTMLVideoElement image, in float sx, in floatsy, in float sw, in float sh, in float dx, in float dy, in floatdw, 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, infloat sh);

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

};

第 6 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

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

};

3.1

canvas的状态

每个上下文都包含一个绘图状态的堆,绘图状态包含下列内容:



当前的transformation matrix.



当前的clipping region



当前的属性值:fillStyle, font, globalAlpha, globalCompositeOperation, lineCap, lineJoin, lineWidth, miterLimit, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY, strokeStyle, textAlign, textBaseline

注:当前path和当前bitmap不是绘图状态的一部分,当前path是持久存在的,仅能被beginPath()复位,当前bitmap是canvas的属性,而非绘图上下文。

context . restore() //弹出堆最上面保存的绘图状态

第 7 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

context . save() //在绘图状态堆上保存当前绘图状态

绘图状态可以看作当前画面应用的所有样式和变形的一个快照。而状态的应用则可以避免绘图代码的过度膨胀。

3.2

转换(Transformations)

当建立形状和路径时,转换矩阵被应用到其坐标上。转换的执行顺序是严格按顺序的(注:原文是反向,经试验应该是按调用顺序的)。

在做转换/变形之前先保存状态是一个良好的习惯。大多数情况下,调用 restore 方法比手动恢复原先的状态要简单得多。又,如果你是在一个循环中做位移但没有保存和恢复 canvas 的状态,很可能到最后会发现怎么有些东西不见了,那是因为它很可能已经超出 canvas 范围以外了。

context . rotate(angle) //按给定的弧度旋转,按顺时针旋转

rotate方法旋转的中心始终是canvas的原点,如果要改变它,需要使用translate方法。

context.translate(75,75);

for (var i=1;i<6;i++){

context.save();

context.fillStyle = 'rgb('+(51*i)+','+(255-51*i)+',255)';

for (var j=0;j<i*6;j++){ context.rotate(Math.PI*2/(i*6));

context.beginPath();

context.arc(0,i*12.5,5,0,Math.PI*2,true);

context.fill();

}

context.restore();

}

context . scale(x, y) //按给定的缩放倍率缩放,1.0,为不变

参数比1.0小表示缩小,否则表示放大。默认情况下,canvas 的 1 单位就是 1 个像素。举例说,如果我们设置缩放因子是 0.5,1 个单位就变成对应 0.5 个像素,这样绘制出来的形状就会是原先的一半。同理,设置为 2.0 时,1 个单位就对应变成了 2 像素,绘制的结果就是图形放大了 2 倍。

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

第 8 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

重设当前的转换到

context . transform(m11, m12, m21, m22, dx, dy) //矩阵变换,结果等于当前的变形矩阵乘上

m11

m21

dx

m12

m22

dy

0

0

1

后的结果

context . translate(x, y) //可以理解为偏移,向x,y方向偏移指定的量,其用来移动Canvas的原点到一个指定的值

下面是一个利用translate方法进行绘制螺旋图案的例子 :

//绘制螺旋图案的函数

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

第 9 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

ctx.lineTo(x2,y2);

x1 = x2;

y1 = y2;

i++;

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

ctx.stroke();

}

//调用部分代码

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

}

}

3.3

合成(Compositing)

在默认情况下,我们总是将一个图形画在另一个之上,但在特殊情况下,这样是不够的。比如说,它这样受制于图形的绘制顺序。不过,我们可以利用 globalCompositeOperation 属性来改变这些做法

context . globalAlpha [ = value ] //0-1.0之间的数据,设定图像的透明度

context . globalCompositeOperation [ = value ] //设定重叠图像的覆盖方式,可以设定为(注,值大小写敏感):

注意:下面所有图例中,B(蓝色方块)是先绘制的,即“已有的 canvas 内容”,A(红色圆形)是后面绘制,即“新图形”。

source-over (default)

A over B. 这是默认设置,新图形会覆盖在原有内容之上。

destination-over

B over A. 会在原有内容之下绘制新图形。

第 10 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

source-atop

A atop B. 新图形中与原有内容重叠的部分会被绘制,并覆盖于原有内容之上。

destination-atop

B atop A. 原有内容中与新内容重叠的部分会被保留,并会在原有内容之下绘制新图形

source-in

A in B. 新图形会仅仅出现与原有内容重叠的部分。其它区域都变成透明的。

destination-in

B in A. 原有内容中与新图形重叠的部分会被保留,其它区域都变成透明的

source-out

A out B. 结果是只有新图形中与原有内容不重叠的部分会被绘制出来。

destination-out

B out A. 原有内容中与新图形不重叠的部分会被保留。

lighter

A plus B. 两图形中重叠部分作加色处理。

darker

两图形中重叠的部分作减色处理。

*标准中没有暂无此项

第 11 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

copy

A (B is ignored). 只有新图形会被保留,其它都被清除掉.

xor

A xor B. 重叠的部分会变成透明。

vendorName-operationName

Vendor-specific extensions to the list of composition operators should use this syntax

3.4

颜色和风格

context . fillStyle [ = value ] //返回填充形状的当前风格,能被设置以用来改变当前的填充风格,其值可以是CSS颜色字串,也可以是CanvasGradient或者CanvasPattern对象,非法的值将被忽略。

context . strokeStyle [ = value ] //返回当前描绘形状的风格,能被设置,其值同上。

设置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);

绘制的图形如下所示。

上面提到的还有CanvasGradient对象,规范规定有两类渐变类型,线性渐变和径向渐变。

gradient . addColorStop(offset, color) //在给定偏移的地方增加一个渐变颜色点,偏移量取值范围为0-1.0之间,否则产生一个INDEX_SIZE_ERR的异常,color为DOM字符串,如果不能解析,则抛出一个SYNTAX_ERR的异常

gradient = context . createLinearGradient(x0, y0,

第 12 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

x1, y1) //建立一个线性渐变,如果任何一个参数不是有限值,则抛出一个NOT_SUPPORTED_ERR的异常。

gradient = context . createRadialGradient(x0, y0, r0, x1, y1, r1) //建立一个径向渐变,如果任何一个参数不是有限值,则抛出一个NOT_SUPPORTED_ERR的异常。假如r0或r1为负值,则抛出INDEX_SIZE_ERR的异常。

设置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);

绘制的图形如下所示。

更改var gradient = context.createLinearGradient(0,2,420,2);为

var gradient = context.createLinearGradient(0,2,420,200);则绘制图形如下:

细心的读者会发现,此方法与PHOTOSHOP软件中的渐变工具类似。

注:如果X0=X1,Y0=Y1,则绘制动作什么也不做,自己改改例子试试吧。

createRadialGradient(x0,y0,r0,x1,y1,r1)方法有六个参数,前三个参数表示开始的圆,其圆点在(x0,y0),半径为r0,后三个表示结束的圆,参数意义同上。其绘制过程如下:

第 13 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

1.如果起始圆和结束圆重叠,则不绘制任何东西,并终止步骤;

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,圆锥体的结束圆使用颜色偏移量为1.0,面积外的颜色均使用透明黑。

设置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);

绘制的图形如下所示。

上面提到可以作为渲染风格还有图案对象:CanvasPattern,其调用格式如下:

pattern = context . createPattern(image, repetition)

本方法用指定的图像和重复方向建立一个画布图案对象,image参数可以为img,canvas,video元素中的任一个,如果不满足此条件,则抛出

第 14 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

TYPE_MISMATCH_ERR异常,如果图片编码未知或没有图像数据,则抛出INVALID_STATE_ERR异常;第二个参数可以是下列值:

repeat

默认参数,如果为空,则为此参数,表示两个方向重复

repeat-x

仅水平重复

repeat-y

仅垂直重复

no-repeat

不重复

如果image参数是一个HTMLImageElement对象,但对象的complete属性是false,则执行时抛出INVLAID_STATE_ERR异常;

如果image参数是一个HTMLVideoElement对象,但其readyState属性是HAVE_NOTHING或HAVE_METADATA,则执行时抛出抛出INVLAID_STATE_ERR异常;

如果image参数是一个HTMLCanvasElement对象,但其width属性或height属性是0,则执行时抛出抛出INVLAID_STATE_ERR异常。

图案的绘制时从左上角开始的,根据不同的参数进行重复绘制。如果传递的图片是动画,则选取海报或第一帧作为其绘制图案源,如果使用HTMLVideoElement为对象,则当前播放位置帧被作为图案源。

设置HTML的核心代码如下:

<img id="psrc" src="b.jpg" width="30" height="30"></img>

<button onClick="drawCanvas()">绘制图形</button>

<button onClick="Show()">显示图形</button>

<div>

<canvas id="myCanvas" width="500" height="500" style="border:1px dotted #000">your browser does not support the canvas tag

</canvas>

</div>

设置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中的显示效果如图所示:

第 15 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

repeat效果

Repeat-x效果

Repeat-y效果

3.5

线风格

操作线风格的方法有4个,格式如下:

context . lineCap [ = value ] //返回或设置线段的箭头样式,仅有三个选项:butt(默认值),round,square;其他值忽略

butt

每根线的头和尾都是长方形,也就是不做任何的处理,为默认值

round

每根线的头和尾都增加一个半圆形的箭头

square

每根线的头和尾都增加一个长方形,长度为线宽一半,高度为线宽

三种风格的比较图,JS代码如下

context.beginPath();

context.lineCap='butt';

context.moveTo(100,50);context.lineTo(250,50);

context.stroke();

context.beginPath();

context.lineCap='round';

context.moveTo(100,80); ;context.lineTo(250,80);

context.stroke();

context.beginPath();

context.lineCap='square';

context.moveTo(100,110);context.lineTo(250,110);

第 16 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

context.stroke();

context . lineJoin [ = value ] ///返回或设置线段的连接方式,仅有三个选项:miter(默认值),round,bevel;其他值忽略

miter

线段在连接处外侧延伸直至交于一点,为默认值,外延效果受miterLimit的值影响,当外延交点距离大于限制值时,则表现为bevel风格

round

连接处是一个圆角,圆的半径等于线宽

bevel

连接处为斜角

三种风格的比较图

context . lineWidth [ = value ] //返回或设置线段的线宽,非大于0的值被忽略;默认值为1.0;

context . miterLimit [ = value ] //返回或设置线段的连接处的斜率,非大于0的值被忽略;默认值为10.0。本属性翻译不够准确,请参看英文部分

线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。因为画布的坐标并不和像素直接对应,当需要获得精确的水平或垂直线的时候要特别注意。

想要获得精确的线条,必须对线条是如何描绘出来的有所理解。见下图,用网格来代表 canvas 的坐标格,每一格对应屏幕上一个像素点。在第一个图中,填充了 (2,1) 至 (5,5) 的矩形,整个区域的边界刚好落在像素边缘上,这样就可以得到的矩形有着清晰的边缘。

如果你想要绘制一条从 (3,1) 到 (3,5),宽度是 1.0 的线条,你会得到像第二幅图一样的结果。实际填充区域(深蓝色部分)仅仅延伸至路径两旁各一半像素。而这半个像素又会以近似的方式进行渲染,这意味着那些像素只是部分着色,结果就是以实际笔触颜色一半色调的颜色来填充整个区域

第 17 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

(浅蓝和深蓝的部分)。

要解决这个问题,你必须对路径施以更加精确的控制。已知粗 1.0 的线条会在路径两边各延伸半像素,那么像第三幅图那样绘制从 (3.5,1) 到 (3.5,5) 的线条,其边缘正好落在像素边界,填充出来就是准确的宽为 1.0 的线条。

对于那些宽度为偶数的线条,每一边的像素数都是整数,那么你想要其路径是落在像素点之间 (如那从 (3,1) 到 (3,5)) 而不是在像素点的中间。如果不是的话,端点上同样会出现半渲染的像素点。

3.6

阴影(Shadows)

有关阴影的四个全局属性将影响所有的绘画操作。有关定义如下:

context . shadowBlur [ = value ] //返回或设置阴影模糊等级,非大于等于0的值被忽略;

context . shadowColor [ = value ] //返回或设置阴影颜色

context . shadowOffsetX [ = value ]

context . shadowOffsetY [ = value ] //返回或设置阴影的偏移量

注意:上面的值均不受坐标转换的影响,可以看做是绝对值。

在上面的例子中增加下列语句,可以得到设置阴影的图像:

context.shadowBlur=7;

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

context.shadowOffsetX = 3;

context.shadowOffsetY=3;

3.7

简单形状(矩形)

形状的绘制不影响当前路径(path),形状是剪切区域的主题,也是阴影(Shadow)效果,全局透明(alpha),全局组合(composition)操作等的主题。其由下面三个方法来进行简单的操作:

第 18 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

context . clearRect(x, y, w, h) \\在给定的矩形内清除所有的像素为透明黑(transparent black)

context . fillRect(x, y, w, h) //用当前的填充风格填充给定的区域

context . strokeRect(x, y, w, h) //使用当前给定的线风格,绘制一个盒子区域,影响其绘制风格的有:strokeStyle,lineWidth,lineJoin,miterLimit(可能)。

3.8

复杂形状(路径-paths)

绘图上下文总有一个当前路径,并且是仅此一个,它不是绘图状态的一部分。

一个路径有0个或多个子路径列表。每个子路径包含一个或多个点列表(这些点组成直的或弯曲的线段),和一个标识子路径是否闭合的标志。少于两个点的子路径在绘图时被忽略。操作这些形状的方法稍微多些,如下所示:

默认情况下,图形上下文的路径有0个子路径。

3.8.1

路径起始函数

调用格式:

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

context . closePath() //闭合路径

方法概述:

beginPath方法重设绘图上下文的子路径列表,并清空所有的子路径。

closePath方法在绘图上下文如果没有子路径时,什么也不做;否则,它先把最后一个子路径标示为闭合,然后建立一个包含最后子路径的第一个点的子路径,并加入到绘图上下文。有点拗口,其一般可以看为,假如最后一个子路径,我们命名为spN,假设spN有多个点,则用直线连接spN的最后一个点和第一个点,然后关闭此路径和moveTo到第一个点。

3.8.2

绘制函数

调用格式:

context . stroke()

context . fill()

context . clip()

方法概述:

stroke方法使用lineWidth,lineCap,lineJoin,以及strokeStyle对所有的子路径进行填充。

fill方法使用fillStyle方式填充子路径,未闭合的子路径在填充式按照

第 19 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

闭合方式填充,但并不影响实际的子路径集合。

clip方法使用计算所有的子路径而建立新的剪切区域,未闭合的子路径在填充式按照闭合方式填充,但并不影响实际的子路径集合,新的剪切区域将替换当前的剪切区域。

对于剪切,也许需要一个小节才能说明白,这里我摘抄来自mozilla的教程来阐述剪切的应用。

3.8.3

剪切(clip)

裁切路径和普通的 canvas 图形差不多,不同的是它的作用是遮罩,用来隐藏没有遮罩的部分。如下图所示。红边五角星就是裁切路径,所有在路径以外的部分都不会在 canvas 上绘制出来。

如果和上面介绍的 globalCompositeOperation 属性作一比较,它可以实现与 source-in 和 source-atop 差不多的效果。最重要的区别是裁切路径不会在 canvas 上绘制东西,而且它永远不受新图形的影响。这些特性使得它在特定区域里绘制图形时相当好用。

我们用 clip 方法来创建一个新的裁切路径。默认情况下,canvas 有一个与它自身一样大的裁切路径(也就是没有裁切效果)。

下面展示一个随机星星的例子,并且我们会用clip来限制星星出现的区域。

首先,我画了一个与 canvas 一样大小的黑色方形作为背景,然后移动原点至中心点。然后用 clip方法创建一个弧形的裁切路径。裁切路径也属于 canvas 状态的一部分,可以被保存起来。如果我们在创建新裁切路径时想保留原来的裁切路径,我们需要做的就是保存一下 canvas 的状态。

裁切路径创建之后所有出现在它里面的东西才会画出来。在画线性渐变时这个就更加明显了。然后在随机位置绘制 50 大小不一(经过缩放)的颗,

第 20 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

当然也只有在裁切路径里面的星星才会绘制出来。

代码如下:

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

第 21 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

ctx.fill();

ctx.restore();

}

3.8.4

辅助方法—点是否在路径里

调用格式:

context . isPointInPath(x, y)

方法概述:

给定的坐标(x,y)是否在当前路径中,坐标(x,y)为绘图坐标系坐标,并不受转换的影响。

3.8.5

moveTo方法

调用格式:

context . moveTo(x, y)

方法概述:

建立新的子路径,并制定其第一个点为(x,y)。

3.8.6

lineTo方法

调用格式:

context . lineTo(x, y)

方法概述:

如果绘图上下文没有子路径,则其等同于moveTo(x,y),否则,其建立一条在子路径最后一个点到给定点的直线,并增加(x,y)到子路径中。

3.8.7

rect方法

调用格式:

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

方法概述:

本方法建立二个新的子路径,第一个子路径包含四个点:(x,y),(x+w,y),(x+w,y+h),(x,y+h),四个点的连接方式为直线,该子路径被标示为闭合路径;最后再增加一个子路径,其仅有一个点(x,y)。

第 22 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

3.8.8

圆弧

方法调用格式:

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

方法概述:本方法先增加一条直线到子路径列表,然后增加一个圆弧子路径到子路径列表。直线子路径是由上一个点到圆弧子路径的起始点,而圆弧则为按照给定的开始角度、结束角度和半径描述的按照给定的方向[布尔类型,anticlockwise-逆时针(true)]圆弧上;假如半径为负值,抛出INDEX_SIZE_ERR的异常;

蓝线表示的即是此函数绘制的结果,最左边的点为上一个路径的最后一个点

JS代码:

context.beginPath();

context.moveTo(100,50);

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

context.stroke();

注释掉moveTo语句,则仅仅绘制圆弧:

第 23 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

3.8.9

最短圆弧

方法调用格式:

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

方法概述:本方法绘制出子路径最后一个点(x0,y0)和(x1,y1)以及(x1,y1)和(x2,y2)构成的两条直线间半径为radius的最短弧线,并用直线连接(x0,y0);假如半径为负值,抛出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();

3.8.10

二次方、三次方贝塞尔曲线

贝塞尔曲线的一般概念:在数学的数值分析领域中,贝赛尔曲线(Bezier curve)是电脑图形学中相当重要的参数曲线。更高维度的贝赛尔曲线被称作贝塞尔曲面。对于n阶贝塞尔曲线可如下推断,给定P0、P1、P2…Pn,其贝赛尔曲线即为

nnnnniinininitPttPtPttPtB







...)1()1()1(11100 , 1,0t

用平常话说,n阶的贝赛尔曲线就是双n-1阶贝赛尔曲线之间的插值。

由公式可以得出二次方贝塞尔曲线公式如下:

22120)1(2)1(tPttPtPtB ,1,0t

第 24 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

TrueType字型就运用了以贝塞尔样条组成的二次方贝赛尔曲线。

方法调用格式:

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

quadraticCurveTo(cpx, cpy, x, y)

方法概述:上面分别是三次贝赛尔曲线和二次贝赛尔曲线的调用格式。其主要区别在于控制曲线的控制点式不一样的。其起始点均为子路径的最后一个点,结束点均为(x,y);在最后均要把(x,y)点加入到子路径中。

其绘制图形的例子如下,三次贝赛尔曲线有两个红点作为曲线平滑的控制点,而二次贝塞尔曲线仅有一个控制点。

JS代码如下:

context.moveTo(10,10);

context.quadraticCurveTo(10,50,100,100);

context.stroke();

3.9

文字

绘图上下文提供了得到和设置文字样式的接口方法,这里将一一介绍给大家。

获得和设置文字设置: context.font[=value],

可以参考CSS中对font风格的设置。

IE9对中文的支持好像没有添加,我么有试出来。

获取或设置文字对齐方式:context.textAlign[=value],取值如下:

start

默认值,与canvas风格中的direction定义有关

end

与canvas风格中的direction定义有关

left

左

right

右

center

居中

获得和设置文字对齐基线:context.textBaseline[=value],value的取值如下:

alphabetic

默认值,alphabetic基线

top

文字矩形的顶部

bottom

文字矩形的底部

middle

文字矩形的中间

hanging

Hanging基线

ideographic

Ideographic基线

第 25 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

绘制文字的方法:context.fillText(text,x,y[,maxWidth])

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

前一个方法为绘制填充的文字,后一个方法为对文字进行描边,不填充内部区域。

按照当前字体对给定的文字进行测量:

metrics = context.measureText(text),该方法返回一个TextMetrics对象,可以调用对象的width属性得到文字的宽度。

3.10

绘制图片

要在绘图上下文中绘制图片,可以使用drawImage方法。该方法有三种不同的参数:



drawImage(image,dx,dy)



drawImage(image,dx,dy,dw,dh)



drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)

其中的image参数可以是HTMLImageElement、HTMLCanvasElement和HTMLVideoElement中的任一个对象。

绘制参数的含义可以参看下图:

异常:如果第一个参数不是指定的元素类型,抛出一个TYPE_MISMATCH_ERR异常,如果图片不能进行解码,则抛出INVALID_STATE_ERR异常,如果第二个参数不是允许的值,则抛出SYNTAX_ERR异常。

参数默认值:如果没有指定dw和dh,则默认等于sw和sh,如果sx,sy,sw,sh均没有提供,则默认为sx,xy=0,0;sw和sh为图片的像素宽高。

下面给出图片的几种调用方式:

1.引用页面内图片:

我们可以通过 document.images 集合、document.getElementsByTagName 方法又或者 document.getElementById 方法来获取页面内的图片(如果已知图片元素的 ID。

第 26 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

2.引用canvas元素

和引用页面内的图片类似地,用 document.getElementsByTagName 或 document.getElementById 方法来获取其它 canvas 元素。但你引入的应该是已经准备好的 canvas。一个常用的应用就是为另一个大的 canvas 做缩略图。

3.创建图像

我们可以用脚本创建一个新的 Image对象,但这种方法的主要缺点是如果不希望脚本因为等待图片装置而暂停,还得需要突破预装载。

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

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

当脚本执行后,图片开始装载。若调用 drawImage 时,图片没装载完,脚本会等待直至装载完毕。如果不希望这样,可以使用 onload 事件:

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

img.onload = function(){

// 执行 drawImage 语句

}

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

如果你只用到一张图片的话,这已经够了。但一旦需要不止一张图片,那就需要更加复杂的处理方法,但图片预装载策略超出本规范的范围。

4.通过 data: url 方式嵌入图像

我们还可以通过 data: url 方式来引用图像。Data urls 允许用一串 Base64 编码的字符串的方式来定义一个图片。其优点就是图片内容即时可用,无须再到服务器兜一圈。(还有一个优点是,可以将 CSS,JavaScript,HTML 和 图片全部封装在一起,迁移起来十分方便。)缺点就是图像没法缓存,图片大的话内嵌的 url 数据会相当的长,例如:

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=’上述变量值’>的方法显示出上面的图片。

3.11

像素级操作

2D Context API 提供了三个方法用于像素级操作:createImageData, getImageData, 和putImageData。

第 27 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

ImageData对象保存了图像像素值。每个对象有三个属性: width, height 和data。data 属性类型为CanvasPixelArray,用于储存width*height*4个像素值。每一个像素有RGB值和透明度alpha值(其值为 0 至255,包括alpha在内)。像素的顺序从左至右,从上到下,按行存储。

3.11.1

createImageData方法

imagedata = context . createImageData(sw, sh)

imagedata = context . createImageData(imagedata)

方法概述:createImageData方法根据给定的CSS像素宽高或指定的imagedata具有的宽高建立一个ImageData对象,该对象为透明黑。该方法具体实例化一个新的空ImageData对象。

3.11.2

getImageData方法

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

方法概述:getImageData方法根据给定的绘图画布矩形面积(sx,sy,sw,sh),生成画布上该矩形面积的图形内容,并综合为ImageData对象返回。画布外的像素作为透明黑返回。

3.11.3

putImageData方法

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

方法概述:在绘图画布上绘制给定的ImageData对象。假如脏矩形被提供,则只有在脏矩形上面的像素被绘制。本方法对全局透明、阴影和全局组合属性均忽略。

异常:假如第一个参数不是ImageData对象,抛出TYPE_MISMATCH_ERR异常,假如任一数字参数是无穷或非数字,则抛出NOT_SUPPORTED_ERR错误

3.11.4

演示例子

下面展示了对一张图片进行反色、透明的一个例子,从例子中可以看出,有了像素级的控制能力,我们可以很轻易的对原有图片进行各种图像滤镜操作。图示如下:

JS代码:[当你在word中选择上面的图片,会发现反色滤镜常用在选择

第 28 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

操作里]

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<n;i+=4)

{

pix[i] = 255 - pix[i]; //红

pix[i+1] = 255-pix[i+1]; //绿

pix[i+2] = 255-pix[i+2]; //蓝

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<n;i+=4)

{

pix[i] = pix[i]; //红

pix[i+1] = pix[i+1]; //绿

pix[i+2] = pix[i+2]; //蓝

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

}

context.putImageData(imgd,260,10);

3.12

绘图模型【此段翻译不怎么样,可以参看原英文】

在本文描述的画布中绘图,浏览器一般按照下面的顺序进行绘制:

1.准备形状或图片,此

时图片假设为A,形状必须被所有属性描述的形状,且经过坐标转换;

2.当绘制阴影时,准备图片A,并绘制阴影,形成图片

B;

3.当绘制阴影时,为B

的每个像素乘上alpha值;

4.当绘制阴影时,则根据组合参数对B

和本画布剪贴区域内的图片进行组合;

5.在图片A

上每个像素乘上alpha值;

6.在图片A

上根据组合参数对A和本画布剪贴区域内的图片进行组合

4,5,6章节未被翻译。

4

参考资料

[BEZIER] Courbes à poles, P. de Casteljau. INPI, 1959.

[CSS] Cascading Style Sheets Level 2 Revision 1, B. Bos, T. Çelik,

第 29 页 共 30 页

W3C Canvas 2D API 规范 1.0 by codeEx.cn

第 30 页 共 30 页

I. Hickson, H. Lie. W3C, April 2009.

[CSSCOLOR] CSS Color Module Level 3, T. Çelik, C. Lilley, L. Baron. W3C, August 2008.

[CSSFONTS] CSS Fonts Module Level 3, J. Daggett. W3C, June 2009.

[CSSOM] Cascading Style Sheets Object Model (CSSOM), A. van Kesteren. W3C, December 2007.

[ECMA262] ECMAScript Language Specification. ECMA, December 1999.

[GRAPHICS] (Non-normative) Computer Graphics: Principles and Practice in C, Second Edition, J. Foley, A. van Dam, S. Feiner, J. Hughes. Addison-Wesley, July 1995. ISBN 0-201-84840-6.

[HTML5] HTML 5, I. Hickson, D. Hyatt, eds. World Wide Web Consortium, 23 April 2009, work in progress. The latest edition of HTML 5 is available at http://www.w3.org/TR/html5/.

[IEEE754] IEEE Standard for Floating-Point Arithmetic (IEEE 754). IEEE, August 2008. ISBN 978-0-7381-5753-5.

[PNG] Portable Network Graphics (PNG) Specification, D. Duce. W3C, November 2003.

[PORTERDUFF] Compositing Digital Images, T. Porter, T. Duff. In Computer graphics, volume 18, number 3, pp. 253-259. ACM Press, July 1984.

[RFC2119] Key words for use in RFCs to Indicate Requirement Levels, S. Bradner, March 1997. Available at http://tools.ietf.org/html/rfc2119. =======

[RFC2119] Key words for use in RFCs to Indicate Requirement Levels, S. Bradner, March 1997. Available at http://tools.ietf.org/html/rfc2119.

[HTML5] HTML 5, I. Hickson, D. Hyatt, eds. World Wide Web Consortium, 23 April 2009, work in progress. This edition of HTML 5 is http://www.w3.org/TR/2009/WD-html5-20090423/. The latest edition of HTML 5 is available at http://www.w3.org/TR/html5/. >>>>>>> 1.1 =======

 

你可能感兴趣的:(html5 canvas)