头闻号

东莞市石排赣南塑胶五金厂

音箱|轻触开关|汽车影音|注塑加工|综合性公司|塑料模

首页 > 新闻中心 > 科技常识:HTML5 Canvas标签使用收录
科技常识:HTML5 Canvas标签使用收录
发布时间:2024-10-01 08:30:45        浏览次数:2        返回列表

今天小编跟大家讲解下有关HTML5 Canvas标签使用收录 ,相信小伙伴们对这个话题应该有所关注吧,小编也收集到了有关HTML5 Canvas标签使用收录 的相关资料,希望小伙伴们看了有所帮助。

一、基本概念

什么是Canvas

<canvas>是一个新的HTML元素 这个元素在HTML5 中被定义。这个元素通常可以被用来在HTML页面中通过Javascript进行绘制图形、合成图像等等操作 也可以用来做一些动画。当然 目前HTML5规范还在草稿阶段 正式发布也许要等到2010年 不过现在已经有不少浏览器已经支持了部分HTML5规范。目前支持canvas元素的浏览器有Firefox3+、Safari4、Chrome2.0+等 因此 在运行本页中的例子时 请确保你使用的是上述浏览器之一。

尽管在Mozilla 已经有不少关于Canvas的教程 我还是决定把自己的学习过程记录下来。如果觉得我写的不够明白 那么你可以在参考资料中找到Mozilla网站上Canvas教程的链接。

另外 可以在这里 找到一些有趣的Canvas示例

开始使用Canvas

使用Canvas很简单 与使用其他HTML元素一样 只需要在页面中添加一个<canvas>标签即可:

代码如下:<canvas id="screen" width="400" height="400"></canvas>

当然 这样只是简单的创建了一个Canvas对象而已 并没有对它进行任何操作 这个时候的canvas元素看上去与div元素是没什么区别的 在页面上什么都看不出来:)另外 canvas元素的大小可以通过width与height属性来指定 这与img元素有点相似。

Canvas的核心:Context前面说到可以通过Javascript来操作Canvas对象来进行绘制图形、合成图像等操作 这些操作并不是通过Canvas对象本身来进行的 而是通过Canvas对象的一个方法getContext获取Canvas操作上下文来进行。也就是说 在后面我们使用Canvas对象的过程中 都是与Canvas对象的Context打交道 而Canvas对象本身可以用来获取Canvas对象的大小等信息。要获取Canvas对象的Context很简单 直接调用canvas元素的getContext方法即可 在调用的时候需要传递一个Context类型参数 目前可以用的并且是唯一可以用的类型值就是2d:

<canvas id="screen" width="400" height="400"></canvas> <script type="text/javascript"> var canvas = document.getElementById("screen"); var ctx = canvas.getContext("2d"); </script>

Firefox3.0.x的尴尬

Firefox3.0.x虽然支持了canvas元素 但是并没有完全按照规范来实现 规范中的fillText、 measureText两个方法在Firefox3.0.x中被几个Firefox特有的方法代替 因此在Firefox3.0.x中使用Canvas时需要先fix这个几个方法在不同浏览器中的差别。

下面这代码取自MozillaBespin 项目 它修正了Firefox3.0.x中Canvas的Context对象与HTML5规范不一致的地方:

function fixContext(ctx) { // * upgrade Firefox 3.0.x text rendering to HTML 5 standard if (!ctx.fillText && ctx.mozDrawText) { ctx.fillText = function(textToDraw, x, y, maxWidth) { ctx.translate(x, y); ctx.mozTextStyle = ctx.font; ctx.mozDrawText(textToDraw); ctx.translate(-x, -y); }; } // * Setup measureText if (!ctx.measureText && ctx.mozMeasureText) { ctx.measureText = function(text) { if (ctx.font) ctx.mozTextStyle = ctx.font; var width = ctx.mozMeasureText(text); return { width: width }; }; } // * Setup html5MeasureText if (ctx.measureText && !ctx.html5MeasureText) { ctx.html5MeasureText = ctx.measureText; ctx.measureText = function(text) { var textMetrics = ctx.html5MeasureText(text); // fake it 'til you make it textMetrics.ascent = ctx.html5MeasureText("m").width; return textMetrics; }; } // * for other browsers, no-op away if (!ctx.fillText) { ctx.fillText = function() {}; } if (!ctx.measureText) { ctx.measureText = function() { return 10; }; } return ctx; }

注意:到Opera9.5为止 Opera还不支持HTML5规范中Canvas对象的fillText以及其相关方法和属性。

Hello,Canvas!

在对Canvas进行了一些初步了解后 开始来写我们的第一个Canvas程序 闻名的HelloWorld的又一个分支“Hello,Canvas”:

<canvas id="screen" width="400" height="400"></canvas> <script type="text/javascript"> (function() { var canvas = document.getElementById("screen"); var ctx = fixContext(canvas.getContext("2d")); ctx.font = "20pt Arial"; ctx.fillText("Hello, Canvas!", 20, 20); ctx.fillText("www.xujiwei.com", 20, 50); function fixContext(ctx) { // * upgrade Firefox 3.0.x text rendering to HTML 5 standard if (!ctx.fillText && ctx.mozDrawText) { ctx.fillText = function(textToDraw, x, y, maxWidth) { ctx.translate(x, y); ctx.mozTextStyle = ctx.font; ctx.mozDrawText(textToDraw); ctx.translate(-x, -y); }; } // * Setup measureText if (!ctx.measureText && ctx.mozMeasureText) { ctx.measureText = function(text) { if (ctx.font) ctx.mozTextStyle = ctx.font; var width = ctx.mozMeasureText(text); return { width: width }; }; } // * Setup html5MeasureText if (ctx.measureText && !ctx.html5MeasureText) { ctx.html5MeasureText = ctx.measureText; ctx.measureText = function(text) { var textMetrics = ctx.html5MeasureText(text); // fake it 'til you make it textMetrics.ascent = ctx.html5MeasureText("m").width; return textMetrics; }; } // * for other browsers, no-op away if (!ctx.fillText) { ctx.fillText = function() {}; } if (!ctx.measureText) { ctx.measureText = function() { return 10; }; } return ctx; } })(); </script>

运行示例 Canvas对象所在区域显示出“Hello,World!” 这正是代码中ctx.fillText("Hello,World!",20,20);的作用。

fillText以及相关属性

fillText方法用来在Canvas中显示文字 它可以接受四个参数 其中最后一个是可选的:

voidfillText(inDOMStringtext,infloatx,infloaty,[Optional]infloatmaxWidth);

其中maxWidth表示显示文字时最大的宽度 可以防止文字溢出 不过我在测试中发现在Firefox与Chomre中指定了maxWidth时也没有任何效果。

在使用fillText方法之前 可以通过设置Context的font属性来调整显示文字的字体 在上面的示例中我使用了“20ptArial”来作为显示文字的字体 你可以自己设置不同的值来看具体的效果。

二、路径

图形的基础-路径

在Canvas中 所有基本图形都是以路径为基础的 也就是说 我们在调用2dContext的lineTo、rect等方法时 其实就是往已经的context路径集合中再添加一些路径点 在最后使用fill或stroke方法进行绘制时 都是依据这些路径点来进行填充或画线。

在每次开始绘制路径前 都应该使用context.beginPath()方法来告诉Context对象开始绘制一个新的路径 否则接下来绘制的路径会与之前绘制的路径叠加 在填充或画边框时就会出现问题。在绘制完成路径后 可以直接使用context.closePath()方法来关闭路径 或者手动关闭路径。另外 如果在填充时路径没有关闭 那么Context会自动调用closePath方法将路径关闭。

基本路径方法

1.beginPath,closePath

这两个方法在前面已经介绍过 分别用来通知Context开始一个新的路径和关闭当前的路径。

在Canvas中使用路径时 应该要保持一个良好的习惯 每次开始绘制路径前都要调用一次beginPath方法 否则画出来的效果难看不说 还会严重影响性能。

在下面这张图中 左边的图形在每次绘制矩形前都调用了一次beginPath来清除之前的路径并重新开始绘制新的路径 而后面的图形则就只在绘制所有图形前调用了一次beginPath来清除路径 因此 虽然这里是使用的边框色是#666 但是右边的图形颜色比左边的深一些 因为每次使用stroke绘制边框时 会把之前的路径再次绘制一遍 叠加起来颜色就比原来深一些。

<canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.strokeStyle = "#666"; function useBeginPath() { for (var i = 0; i < 5; ++i) { ctx.beginPath(); ctx.rect(10 + i*20, 10 + i*20, 210 - i*40, 210 - i*40); ctx.stroke(); } } function notUseBeginPath() { ctx.beginPath(); for (var i = 0; i < 5; ++i) { ctx.rect(240 + i*20, 10 + i*20, 210 - i*40, 210 - i*40); ctx.stroke(); } } useBeginPath(); notUseBeginPath(); </script>

在Context中路径数较少时 如果不考虑显示效果 性能上还可以接受 但是如果Context中的路径数很多时 在开始绘制新路径前不使用beginPath的话 因为每次绘制都要将之前的路径重新绘制一遍 这时性能会以指数下降。

因此 除非有特殊需要 每次开始绘制路径前都要调用beginPath来开始新路径。

2.移动与直线moveTo,lineTo,rect

<canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(110,110); ctx.lineTo(10, 110); ctx.lineTo(10, 10); ctx.stroke(); ctx.beginPath(); ctx.rect(120, 10, 100, 100); ctx.stroke(); </script>

voidmoveTo(infloatx,infloaty);

在Canvas中绘制路径 一般是不需要指定起点的 默认的起点就是上一次绘制路径的终点 因此 如果需要指定起点的话 就需要使用moveTo方法来指定要移动到的位置。

voidlineTo(infloatx,infloaty);

lineTo方法则是绘制一条直接路径到指定的位置。在调用完lineTo方法后 Context内部的绘制起点会移动到直线的终点。

voidrect(infloatx,infloaty,infloatw,infloath);

rect方法用来绘制一个矩形路径 通过参数指定左上角位置以及宽和高。在调用rect后 Context的绘制起点会移动到rect绘制的矩形的左上角。

rect方法与后面要介绍的arc方法与其他路径方法有一点不同 它们是使用参数指定起点的 而不是使用Context内部维护的起点。

3.曲线arcTo,arc,quadraticCurveTo,bezierCurveTo

voidarcTo(infloatx1,infloaty1,infloatx2,infloaty2,infloatradius);

按照WHATWG文档的说明 这个方法是画一个与两条射线相切的的圆弧 两条射线其中一条为穿过Context绘制起点 终点为(x1,y1) 另外一条为穿过(x2,y2) 终点为(x1,y1) 这条圆弧为最小的与这两条射线相切的圆弧。在调用完arcTo方法后 将圆弧与射线(x1,y1)-(x2,y2)的切点添加到当前路径中 做为下次绘制的起点。

在测试中发现 Firefox和Opera目前对这个方法的支持并不好 只有Chrome和Safari4能绘制出正确的路径。

<canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.strokeStyle = "#000"; ctx.translate(200, 200); ctx.moveTo(10, 10); ctx.arcTo(110, 60, 10, 110, 30); ctx.stroke(); ctx.beginPath(); ctx.strokeStyle = "#999"; ctx.moveTo(10, 6); ctx.lineTo(114, 60); ctx.lineTo(10, 114); ctx.stroke(); </script>

voidarc(infloatx,infloaty,infloatradius,infloatstartAngle,infloatendAngle,inbooleananticlockwise);

arc方法用来绘制一段圆弧路径 通过圆心位置、起始弧度、终止弧度来指定圆弧的位置和大小 这个方法也不 依赖于Context维护的绘制起点。而在画圆弧时的旋转方向则由最后一个参数anticlockwise来指定 如果为true就是逆时针 false则为顺时针。

voidquadraticCurveTo(infloatcpx,infloatcpy,infloatx,infloaty);

quadraticCurveTo方法用来绘制二次样条曲线路径 参数中cpx与cpy指定控制点的位置 x和y指定终点的位置 起点则是由Context维护的绘制起点。

voidbezierCurveTo(infloatcp1x,infloatcp1y,infloatcp2x,infloatcp2y,infloatx,infloaty);

bezierCurveTo方法用来绘制贝塞尔曲线路径 它与quadraticCurveTo相似 不过贝塞尔曲线有两个控制点 因此参数中的cp1x,cp1y,cp2x,cp2y用来指定两个控制点的位置 而x和y指定绺的位置。

<canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.translate(10, 10); ctx.beginPath(); ctx.arc(50, 50, 50, 0, Math.PI, true); ctx.stroke(); // quadraticCurveTo ctx.beginPath(); ctx.strokeStyle = "#000"; ctx.moveTo(110, 50); ctx.quadraticCurveTo(160, 0, 210, 50); ctx.stroke(); ctx.beginPath(); ctx.strokeStyle = "red"; ctx.moveTo(110, 50); ctx.lineTo(160, 0); ctx.lineTo(210, 50); ctx.stroke(); // bezierCurveTo ctx.beginPath(); ctx.strokeStyle = "#000"; ctx.moveTo(220, 50); ctx.bezierCurveTo(250, 0, 280, 10, 320, 50); ctx.stroke(); ctx.beginPath(); ctx.strokeStyle = "red"; ctx.moveTo(220, 50); ctx.lineTo(250, 0); ctx.lineTo(280, 10); ctx.lineTo(320, 50); ctx.stroke(); </script>

4.fill,stroke,clip

fill与stroke这两个方法很好理解 分别用来填充路径与绘制路径线条。

clip方法用来给Canvas设置一个剪辑区域 在调用clip方法之后的代码只对这个设定的剪辑区域有效 不会影响其他地方 这个方法在要进行局部更新时很有用。默认情况下 剪辑区域是一个左上角在(0,0) 宽和高分别等于Canvas元素的宽和高的矩形。

在画这个图时 虽然两次都是使用fillRect(0,0,100,100)填充了一个100x100大小矩形 但是显示的结果却是第二次填充的只是中间的一小块 这是因为在两次填充之间使用clip方法设定了剪辑区域 这样第二次填充时只会影响到所设定的中间那一小部分区域。

<canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.translate(10, 10); // fill a green rectangle ctx.fillStyle = "green"; ctx.fillRect(0, 0, 100, 100); // set the clipping region ctx.beginPath(); ctx.rect(30, 30, 40, 40); ctx.clip(); ctx.stroke(); // fill a yellow rectangle ctx.fillStyle = "yellow"; ctx.fillRect(0, 0, 100, 100); </script>

5.clearRect,fillRect,strokeRect

这三个方法并不是路径方法 而是用来直接处理Canvas上的内容 相当于Canvas的背景 调用这三个方法也不会影响Context绘图的起点。

要清除Canvas上的所有内容时 可以直接调用context.clearRect(0,0,width,height)来直接清除 而不需要使用路径方法绘制一个与Canvas同等大小的矩形路径再使用fill方法去清除。

结语

通过Canvas的路径方法 可以使用Canvas处理一些简单的矢量图形 这样在缩放时也不会失真。不过Canvas的路径方法也不是很强大 至少连个椭圆的路径都没有……

参考资料 1.TheCanvasElement,WHATWG

来源:爱蒂网