HTML5 - canvas 2D绘图

来源:互联网 发布:山西新车上牌数据 编辑:程序博客网 时间:2024/05/16 10:46

文章地址: http://www.forum.nokia.com/

相关链接文章: http://www.ibm.com/developerworks/cn/web/lp/html5/

             http://www.ibm.com/developerworks/cn/web/1012_linlin_html5canvas/index.html?ca=drs-

             http://www.uml.org.cn/site/201010083.asp

 

单独的一个 canvas 标记只是在页面中定义了一块矩形区域,并无特别之处,开发人员只有配合使用 JavaScript 脚本,才能够完成各种图形,线条,以及复杂的图形变换操作。

在开始绘图之前,我们需要首先创建一个指定大小的 canvas,并为其指定一个 id,方便在 JavaScript 脚本中获取该 DOM 实例对象。声明一个 canvas 节点的方式如下所示。

<canvas id="canvas" width="300" height="200"> 
Fallback content, in case the browser does not support Canvas.
</canvas>

需要指明的是,由于无法保证所有用户使用的浏览器都能够支持 canvas 元素,所以在目前开发基于 canvas 的 Web 应用中需要增加“Fallback content”,以提示用户他们无法正常体验此功能的原因或建议他们去下载最新的浏览器。

 

获得上下文context

基于 canvas 的绘图并不是直接在 canvas 标记所创建的绘图画面上进行各种绘图操作,而是依赖画面所提供的 渲染上下文(Rendering Context),所有的绘图命令和属性都定义在渲染上下文当中。在通过 canvas id 获取相应的 DOM 对象之后首先要做的事情就是获取渲染上下文对象。 渲染上下文与 canvas 一一对应,无论对同一 canvas 对象调用几次 getContext() 方法,都将返回同一个上下文对象。目前,所有支持 canvas 标签的浏览器都支持 2D 渲染上下文,可以使用如下的代码来获取该对象。

var context = document.getElementById("canvas").getContext("2d");

绘制矩形

创建好了画布后,让我们来准备画笔。要在画布中绘制图形需要使用 JavaScript 。首先通过 getElementById 函数找到 canvas元素,然后初始化上下文。之后可以使用上下文 API 绘制各种图形。下面的脚本在 canvas 中绘制一个矩形:

<!DOCTYPE HTML>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
cxt.fillStyle="#FF0000";
cxt.fillRect(0,0,150,75);

</script>

</body>
</html>

上面的页面在浏览器里显示如下:

Html5 canvas rect.png

通过 fillRect 可以绘制带填充的矩形。使用 strokeRect 可以绘制只有边框没有填充的矩形。如果想清除部分 canvas 可以使用 clearRect。上述三个方法的参数相同:x, y, width, height。前两个参数设定 (x,y) 坐标,后两个参数设置矩形的高度和宽度。

 

绘制路径

通过 canvas 路径(path)可以绘制任意形状。可以先绘制轮廓,然后绘制边框和填充。创建自定义形状很简单,使用 beginPath()开始绘制,然后使用直线、曲线和其他图形绘制你的图形。绘制完毕后调用 fill 和 stroke 即可添加填充或者设置边框。调用 closePath() 结束自定义图形绘制。

完整的路径绘制过程大致可以分为如下两个阶段:

  1. 定义路径轮廓:在每个 canvas 实例对象中都拥有一个 path 对象,创建自定义图形的过程就是不断对 path 对象操作的过程。每当开始一次新的图形绘制任务,都需要先使用 beginPath() 方法来重置 path 对象至初始状态,进而通过一系列对 moveTo/lineTo 等画线方法的调用,绘制期望的路径,其中 moveTo(x, y) 方法设置绘图起始坐标,而 lineTo(x,y) 等画线方法可以从当前起点绘制直线,圆弧以及曲线到目标位置。最后一步,也是可选的步骤,是调用 closePath() 方法将自定义图形进行闭合,该方法将自动创建一条从当前坐标到起始坐标的直线。
  2. 绘制路径:定义完路径的轮廓,此时 canvas 画面中没有显示任何路径,开发人员还可以对路径进行修改。一旦确定完成,则需要继续调用 stroke()/fill() 函数来完成将路径渲染到画面的最后一步。路径的轮廓颜色和填充颜色由 strokeStyle 和 fillStyle 属性决定。
<!DOCTYPE HTML>
<html>
<body>

<canvas id="myCanvas" width="200" height="100">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">

var c=document.getElementById("myCanvas");
var context=c.getContext("2d");

// Set the style properties.
context.fillStyle = '#00f';
context.strokeStyle = '#f00';
context.lineWidth = 4;

context.beginPath();
// Start from the top-left point.
context.moveTo(10, 10); // give the (x,y) coordinates
context.lineTo(100, 10);
context.lineTo(10, 100);
context.lineTo(10, 10);

// Done! Now fill the shape and draw the stroke.
// Note: your shape will not be visible until you call any of the two methods.

context.fill();
context.stroke();
context.closePath();

</script>

</body>
</html>

显示效果如下:

Html5 canvas path.png

我们还可以分别试着注释掉context.fill(); 或者 context.stroke(); , 就可以理解fill和stroke的含义了。

文字

context 对象可以设置以下 text 属性:

  • font:文字字体,同 CSS font-family 属性
  • textAlign:文字水平对齐方式。可取属性值: start, end, left, right, center。默认值:start.
  • textBaseline:文字竖直对齐方式。可取属性值:top, hanging, middle,alphabetic, ideographic, bottom。默认值:alphabetic.

有两个方法可以绘制文字: fillText 和 strokeText。第一个绘制带 fillStyle 填充的文字,后者绘制只有 strokeStyle 边框的文字。两者的参数相同:要绘制的文字和文字的位置(x,y) 坐标。还有一个可选选项——最大宽度。如果需要的话,浏览器会缩减文字以让它适应指定宽度。文字对齐属性影响文字与设置的(x,y) 坐标的相对位置。

在本文附带的例子中我们用到了文字的绘制:

ctx.fillStyle    = '#00F';
ctx.font = 'bold 20px sans-serif';
ctx.textBaseline = 'top';
ctx.fillText ('Hello Canvas!', 0, 0);

动画

Canvas 并非为了制作动画而出现,自然没有动画制作中帧的概念。因而,使用定时器不断的重绘 canvas 画面成为了实现动画效果的通用解决方式。Javascript 中的 setInterval(code,millisec) 方法可以按照指定的时间间隔 millisec 来反复调用 code 所指向的函数或代码串,这样,通过将绘图函数作为第一个参数传给 setInterval 方法,在每次被调用的过程中移动画面中图形的位置,来最终达到一种动画的体验。需要注意的一点是,虽然 setinterval 方法的第二个参数允许开发人员对绘图函数的调用频率进行设定,但这始终都是一种最为理想的情况,由于这种绘图频率很大程度上取决于支持 canvas 的底层 JavaScript 引擎的渲染速度以及相应绘图函数的复杂性,因而实际运行的结果往往都是要慢于指定绘图频率的。

下面的例子绘制了不同颜色的贝塞尔曲线:

<html>
<head>
<style>
body {
margin: 0;
}
</style>

</head>

<body>

<canvas id="canvas" width="400" height="400"></canvas>

<script type='text/javascript'>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

var waves = ["rgba(195, 002, 002, 0.6)",
"rgba(174, 000, 000, 0.3)",
"rgba(227, 093, 068, 0.3)",
"rgba(234, 135, 109, 0.3)",
]

var i = 0;

function draw() {
canvas.width = canvas.width;


ctx.fillStyle = '#00F';
ctx.font = 'bold 20px sans-serif';
ctx.textBaseline = 'top';
ctx.fillText ('Hello Canvas!', 0, 0);


for(var j = waves.length - 1; j >= 0; j--) {
var offset = i + j * Math.PI * 12;
ctx.fillStyle = (waves[j]);

var randomLeft = Math.abs(Math.pow( Math.sin(offset/100), 2 )) * 200;
var randomRight = Math.abs(Math.pow( Math.sin((offset/100) + 10), 2 )) * 200;
var randomLeftConstraint = Math.abs(Math.pow( Math.sin((offset/90)+2), 2 )) * 300;
var randomRightConstraint = Math.abs(Math.pow( Math.sin((offset/90)+1), 2)) * 300;

ctx.beginPath();
ctx.moveTo(0, randomLeft + 10);

// ctx.lineTo(canvas.width, randomRight + 10);
ctx.bezierCurveTo(canvas.width / 3, randomLeftConstraint, canvas.width / 3 * 2, randomRightConstraint, canvas.width, randomRight + 10);
ctx.lineTo(canvas.width , canvas.height);
ctx.lineTo(0, canvas.height);
ctx.lineTo(0, randomLeft + 10);

ctx.closePath();
ctx.fill();
}

i++;
}
setInterval("draw()", 20);
</script>
</body>
</html>

 

下图中显示了文字和动画的绘制:

Html5 canvas wave.png

 

总结

本文对 HTML5 新引入的 canvas 元素在 Web 绘图中所扮演的角色和所发挥的作用做了最基本的介绍,其中包括使用 canvas 完成基本的 Web 绘图,动画和交互任务,虽然 Flash,Silverlight 也都可以完成相同的任务,甚至在性能上更胜一筹,但是作为一种不依赖任何插件的标准 Web 像素级绘图技术,我们有理由相信随着各大浏览器厂商的加入,canvas 将会更加成熟完善,也会有更多基于 canvas 的绘图类应用不断涌现。

实例下载:http://www.forum.nokia.com/piazza/wiki/images/7/78/HTML5_Canvas.zip?20110116152415

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 touchdesigner 边界路由 contiki边界路由 个人简历程序 2.编写一个C程序,假设图书馆的图书包含书名、编号和作者等3个属性,读者包含姓名和借书证属性,每位读 pythontcp实现聊天室 jstack RS编译码器 RS编译码器原理 高德地图 导航信息 当前导航路径信息 实时导航信息 高德导航时Navi的信息 高德NaviInfo 安卓蓝牙发送信息 clj.fastble 先采用队列求一条最短迷宫路径长度minlen,再采用栈求所有长度为minlen的最短迷宫路径 iOS蓝牙 pycharm激活 shadowsocks下载 shadowsocks下载 开源沙龙 C++程序设计从键盘中输入两个整数,求这两个整数的最大公约数和最小公倍数。 江南大学五部曲 centos搭建ss 算法之美_源代码发布(8) understand halfaSPIclockcycleproducesaclockedge 贪心算法活动 TRIZ系列-创新原理-17 朴素贝叶斯分类 王者荣耀金币 探索性数据分析演示 治安防控 治安 TRIZ系列-创新原理-19 TRIZ系列-创新原理-20 利用图像的平移、旋转、缩放、镜像等空间几何变换实现对图像的自适应缩放、几何变换等特效 利用图像的平移、旋转、缩放、镜像等空间几何变换实现对图像的几何变换等特效 [Err]1005-Can\'tcreatetable\'item4.#sql-1238_2c\'(