HTML5简单入门系列

前言

本篇详细介绍canvas画布的API。说是详细介绍,也只是一些常用的API及简单实例和说明。LZ本人也还没有看完全部,下篇会介绍剩余的一些内容。

本篇的示例中,LZ加入了注释,为的是只简单介绍API确实挺无聊,也不那么容易理解,看代码看效果才最直接。

canvas APIs

canvas 基础api 介绍

在初始化Javascript函数中,用canvas标签的id获得canvas的DOM对象,并用getContext() 方法获得这个canvas的“2d”上下文对象,之后使用上下文对象调用canvas API 画图。

直线

画直线的功能可以用 beginPath(), moveTo(), lineTo() 和 stroke() 几个方法的组合来实现。

方法 beginPath() 定义了一个新的路径绘制动作的开始。

方法 moveTo() 为指定点创建了一个新的子路径,我们可以把

moveTo() 方法看成用来定位绘图鼠标用的(直线的起点,因为所有画线都和它相关,我们称之为上下文点)。

方法 lineTo() 从鼠标定位点,到方法参数中指定的点之间画一条直线。

方法 stroke() 为所画的线赋予颜色,并使其可见。如果没有特别的指定颜色的话,则默认使用黑色画直线。

上下文对象context的属性

context.lineWidth = 5; //设置宽度

context.strokeStyle = ‘blue‘; //设置颜色

context.lineCap = ‘round‘; //设置直线终点样式,可选值butt(默认值),round,和square。

示例如下

 

效果如图:

弧线

画弧线的方法是 arc()。每条弧线都需要由中心点、半径、起始角度(弧度n*Math.PI)、结束角度(弧度m*Math.PI)和绘图方向(顺时针 false 还是逆时针true)这几个参数来确定。如context.arc(x, y, radius, startAngle, endAngle, antiClockwise);

二次曲线

二次曲线使用quadraticCurveTo()方法来绘制。每条二次曲线要由上下文点、一个控制点和一个终止点来定义。

context.quadraticCurveTo(controlX, controlY, endX, endY);

贝塞尔曲线

绘制贝塞尔曲线使用方法bezierCurveTo() 。每条贝塞尔曲线需要由上下文点、两个控制点和一个终止点来确定。如:

context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);

圆角

画圆角使用方法 arcTo() 。此方法需要一个控制点、一个终止点和半径作为必要的参数。如:

context.arcTo(controlX,controlY,endX,endY,radius);

画路径

路径是由多条子路径连接构成的。每条子路径的终止点就将作为新的上下文点。我们可以使用lineTo(), arcTo(), quadraticCurveTo() 和 bezierCurveTo() 创建新的子路径。每次要开始画一条路径的时候就要使用 beginPath() 方法。

canvas支持3种线条的连接样式,包括: miter, round, 和 bevel。 设定连接样式是用 lineJoin 属性设定。缺省情况下,将使用 miter 样式。

上边几个的代码示例如下:

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5     <title></title>
  6     <script>
  7         window.onload = function () {
  8             ords();
  9             arc();
 10             //quadratic();
 11             //bezier();
 12             //arcTo();
 13             //path();
 14         };
 15         //弧线
 16         function arc() {
 17             var canvas = document.getElementById("myCanvas");
 18             var context = canvas.getContext("2d");
 19             var x = canvas.width / 2, y = canvas.height / 2;//圆心坐标
 20             var radius = 75;                                //半径
 21             var startAngle = 0.5 * Math.PI,                 //开始弧度
 22                 endAngle = 2 * Math.PI,                     //结束弧度
 23                 counterClockwise = false;                   //画图方向,false-顺时针,true-逆时针,注意对绘画效果的影响!!
 24             context.beginPath();
 25             context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
 26             //context.lineWidth = 15;
 27             //context.strokeStyle = "black";
 28             //context.stroke();
 29             context.fillStyle = "blue";
 30             context.fill();
 31         }
 32         //二次曲线
 33         function quadratic() {
 34             var canvas = document.getElementById("myCanvas");
 35             var context = canvas.getContext("2d");
 36
 37             context.beginPath();
 38             context.moveTo(188, 150);//起始点
 39             context.quadraticCurveTo(328, 50, 388, 150);//控制点和结束点
 40             context.lineWidth = 10;
 41             context.strokeStyle = "black";
 42             context.stroke();
 43         }
 44         //贝赛尔曲线
 45         function bezier() {
 46             var canvas = document.getElementById("myCanvas");
 47             var context = canvas.getContext("2d");
 48             context.beginPath();
 49             context.moveTo(188, 130);
 50             context.bezierCurveTo(80, 10, 188, 10, 388, 170);//控制点1,控制点2和结束点
 51             context.lineWidth = 10;
 52             context.strokeStyle = "black";
 53             context.stroke();
 54         }
 55         //圆角
 56         function arcTo() {
 57             var canvas = document.getElementById("myCanvas");
 58             var context = canvas.getContext("2d");
 59             var rectWidth = 200,//矩形框宽度
 60                 rectHeight = 100,//高度
 61                 rectX = 189,//起点
 62                 rectY = 50,
 63                 cornerRadius = 50;//圆角半径
 64             context.beginPath();
 65             context.moveTo(rectX, rectY);
 66             context.lineTo(rectX + rectWidth - cornerRadius, rectY);//直线坐标点,x坐标减去圆角半径
 67             context.arcTo(rectX + rectWidth, rectY, rectX + rectWidth, rectY + cornerRadius, cornerRadius);//圆角起始点坐标和半径
 68             context.lineTo(rectX + rectWidth, rectY + rectHeight);//此时起点y坐标是圆角结束点rectY + cornerRadius
 69             context.lineWidth = 5;
 70             context.stroke();
 71         }
 72         //路径
 73         function path() {
 74             var canvas = document.getElementById("myCanvas");
 75             var context = canvas.getContext("2d");
 76
 77             context.beginPath();
 78             context.lineJoin = "round";//线间链接样式:可选值miter(默认), round, 和 bevel。
 79             context.moveTo(100, 20);
 80             context.lineTo(220, 60);
 81             // 第一条直线
 82             context.lineTo(200, 160);
 83             // 二次曲线
 84             context.quadraticCurveTo(230, 200, 250, 120);
 85             // 贝塞尔曲线
 86             context.bezierCurveTo(290, -40, 300, 200, 400, 150);
 87             // 第二条直线
 88             context.lineTo(500, 90);
 89             context.lineWidth = 15;
 90             context.strokeStyle = "blue";
 91             context.closePath();
 92             context.stroke();
 93
 94         }
 95         //坐标系
 96         function ords() {
 97             for (var i = 0; i < 50; i++) {
 98                 drawDirectedLine(i * 20, 0, false);//纵向,只关心横坐标
 99                 drawDirectedLine(0, i * 20, true);//横向,只关心纵坐标
100             }
101         }
102         //起点坐标,直线方向:true-横向,false-纵向
103         function drawDirectedLine(x1, y1, d) {
104             var canvas = document.getElementById("myCanvas");
105             var context = canvas.getContext("2d");
106             context.beginPath();
107             context.strokeStyle = "#ff3333";
108             if (d) {
109                 context.moveTo(0, y1);
110                 context.lineTo(1000, y1);
111             }
112             else {
113                 context.moveTo(x1, 0);
114                 context.lineTo(x1, 1000);
115             }
116             context.stroke();
117         }
118     </script>
119 </head>
120 <body>
121     <canvas id="myCanvas" width="578" height="250"></canvas>
122 </body>
123 </html>

线性渐变

要使用线性渐变效果填充图形,首先要使用 createLinearGradient() 方法从上下文对象中创建线性渐变对象。

createLinearGradient() 方法的四个参数确定一条虚拟线段,渐变就沿着此条线段的方向。

然后用 addColorStop 方法为线性渐变对象设置渐变线上的关键点的颜色,offset 表示关键点是在渐变虚拟线段的什么位置, offset 的取值范围是0到1,其中0表示是起始点,1表示是终止点,0到1之间的值表示是此虚拟线段中间的某一位置。

再将此线性渐变对象作为填充类型赋值给上下文对象的 fillStyle 属性。canvas将根据渐变虚拟线段上关键点的颜色变化填充图形。

示例代码:

 1  function linear() {
 2             var canvas = document.getElementById("myCanvas");
 3             var context = canvas.getContext("2d");
 4
 5             var grd = context.createLinearGradient(0, 0, 450, 400);//渐变路径从(0,0) 到(450,300)
 6
 7
 8             grd.addColorStop(0, "#000000");
 9             grd.addColorStop(0.5, "#ff0000");
10             grd.addColorStop(1, "#ffffff");
11
12             ////查看渐变效果。
13             //context.beginPath();
14             //context.fillStyle = grd;
15             //context.fillRect(0, 0, 450, 400);
16
17             context.beginPath();
18             context.moveTo(170, 80);//起点
19             context.bezierCurveTo(130, 100, 130, 150, 230, 150);//两个控制点,一个终结点(下一个路径的起点)
20             context.bezierCurveTo(250, 180, 320, 180, 340, 150);
21             context.bezierCurveTo(420, 150, 420, 120, 390, 100);
22             context.bezierCurveTo(430, 40, 370, 30, 340, 50);
23             context.bezierCurveTo(320, 5, 250, 20, 250, 50);
24             context.bezierCurveTo(200, 5, 150, 20, 170, 80);
25             context.closePath();
26
27             //圆周
28             context.strokeStyle = "blue";
29             context.lineWidth = 15;
30             context.closePath();
31             context.stroke();
32             //填充
33             context.fillStyle = grd;
34             context.fill();
35
36         }

效果如图:

      

径向渐变

径向渐变与线性渐变类似,只不过渐变方向不是线段,而是两个圆之间。使用 createRadialGradient() 方法创建渐变对象,参数是渐变起始圆和终止圆。如:

context.createRadialGradient(startX, startY, startRadius, endX, endY, endRadius);

示例代码:

 1  function Radial() {
 2             var canvas = document.getElementById("myCanvas");
 3             var context = canvas.getContext("2d");
 4             context.beginPath();
 5
 6             //三处注释效果不一样,可对比查看
 7             //注释一 示例作图
 8             context.moveTo(170, 80);
 9             context.bezierCurveTo(130, 100, 130, 150, 230, 150);//两个控制点,一个终结点
10             context.bezierCurveTo(250, 180, 320, 180, 340, 150);
11             context.bezierCurveTo(420, 150, 420, 120, 390, 100);
12             context.bezierCurveTo(430, 40, 370, 30, 340, 50);
13             context.bezierCurveTo(320, 5, 250, 20, 250, 50);
14             context.bezierCurveTo(200, 5, 150, 20, 170, 80);
15             context.closePath();
16             // 创建径向渐变对象
17             var grd = context.createRadialGradient(238, 50, 10, 238, 50, 200);//两个圆心+半径
18             // 设置渐变起始圆处的颜色
19             grd.addColorStop(0, "#FF0000");
20             // 设置渐变终止圆处的颜色
21             grd.addColorStop(1, "#00FF00");
22
23             ////注释二 查看渐变效果
24             //context.arc(238, 50, 10, 0, Math.PI * 2, true);
25             ////同心圆效果
26             ////context.arc(238, 50, 200, 0, Math.PI * 2, true);
27             ////非同心圆效果
28             //context.arc(238, 200, 200, 0, Math.PI * 2, true);
29
30             ////注释三  拉开距离 查看两个圆的效果
31             //context.arc(800, 50, 10, 0, Math.PI * 2, true);
32             //context.arc(800, 400, 200, 0, Math.PI * 2, true);
33
34             context.strokeStyle = "blue";
35             context.lineWidth = 2;
36             context.closePath();
37             context.stroke();
38             context.fillStyle = grd;
39             context.fill();
40         }

效果如图:

       

绘制图像

绘制图像需要使用 drawImage() 方法。此方法需要一个图像对象和一个起始点坐标作为参数,其中起始点坐标是相对于canvas的左上角的位置。如:

context.drawImage(imageObj, x, y);

由于 drawImage() 方法需要一个图像对象作为参数,所以我们需要在实际调用 drawImage() 之前就加载图像。这一要求可以通过图像对象的 onload 事件来实现。不过要注意的是, onload 应该在用图像对象的src属性指定图像来源之前就进行赋值。

方法 drawImage() 还可以接受 destWidth 和 destHeight 两个参数用来以任意指定的尺寸显示图像:

context.drawImage(imageObj, x, y, width, height);

方法 drawImage() 还可以增加另六个参数来实现对图像的裁剪。这六个参数是, sourceX,sourceY, sourceWidth, sourceHeight, destWidth 和 destHeight。这六个参数对应的含义可以参阅示意图。  context.drawImage(imageObj, sx, sy, sw, sh, dx, dy, dw, dh);

图片来源(https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/Canvas_tutorial/Using_images#Using_images_which_are_on_the_same_page)

示例代码:

 1 function drawImg() {
 2             var canvas = document.getElementById("myCanvas");
 3             var context = canvas.getContext("2d");
 4             var img = new Image();
 5             //为保证图片加载,在其load方法中添加绘图方法
 6             img.onload = function () {
 7                 context.drawImage(img, 0, 200);//原图输出在位置(0,300)
 8                 context.drawImage(img, 0, 0, 100, 100);//在位置(0,0)将图画成(缩放) 100*100
 9                 context.drawImage(img, 50, 50, 150, 150, 0, 120, 100, 130);//将原图从左上角(50,50)到右下角(150,150)裁剪下来,在位置(0,120)缩放成100*130的图片
10
11                 var pattern = context.createPattern(img, "repeat");
12                 context.fillStyle = pattern;
13                 context.fillRect(0, 400, canvas.width - 20, canvas.height - 20);//填充一个矩形
14             }
15             img.src = "http://w3school.com.cn/i/ct_html5_canvas_image.gif";
16         }

效果图如下:

文本的字体、大小和样式

友情提醒:这里介绍文字略多,可先运行示例,查看效果再回头看介绍,那样就一目了然了。

要设置字体、大小和样式,需要用到上下文对象的 font 属性。样式可以是 normal, italic 或 bold 。默认情况是 normal 。

context.font = ‘italic 40px Calibri‘;

文本的颜色用 fillStyle 属性设置

要描绘字体边缘的效果,要使用 strokeText() 方法替代fillText(),同时要用strokeStyle 属性替代 fillStyle 属性。来自QQ分组大全

文本的对齐功能设定使用 textAlign 属性。其可用的选项包括 start, end, left, center和 right 。对齐的位置是相对于一条虚拟的垂直线,这条线是由 fillText() 或 strokeText() 定义的文本x位置。

垂直对齐文本需要用到 textBaseline 属性。此属性可用的选项包括:top, hanging,middle, alphabetic, ideographic 和 bottom 。默认情况下是alphabetic 。

要获取有关文本的尺度信息,可以使用 measureText() 方法。此方法需要一个文本字符串组为参数,并返回一个尺度对象。尺度对象中的数据是基于所提供的字符串参数和当前的文本字体信息而来的。注意:由于文本的像素高度等于字体尺寸的磅值,所以,从 measureText() 返回的尺度对象并不包含高度数据。如:

var metrics = context.measureText("text");

var width = metrics.width;

示例代码如下:

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5     <title></title>
  6     <script>
  7
  8
  9         window.onload = function () {
 10             font();
 11             wrapText();
 12         };
 13
 14         function font() {
 15             var c = document.getElementById("myCanvas");
 16             var ctx = c.getContext("2d");
 17
 18             // 在位置 300 创建蓝线
 19             ctx.strokeStyle = "blue";
 20             ctx.moveTo(300, 20);
 21             ctx.lineTo(300, 200);
 22             ctx.stroke();
 23
 24             ctx.font = "15px Arial";
 25
 26             // 显示不同的 textAlign 值
 27             ctx.textAlign = "start";
 28             ctx.fillText("textAlign=start", 300, 60);
 29             ctx.textAlign = "end";
 30             ctx.fillText("textAlign=end", 300, 80);
 31             ctx.textAlign = "left";
 32             ctx.fillText("textAlign=left", 300, 100);
 33             ctx.textAlign = "right";
 34             ctx.fillText("textAlign=right", 300, 140);
 35             ctx.textAlign = "center";
 36             ctx.fillText("textAlign=center", 300, 120);
 37
 38             //在位置 y=300 绘制蓝色线条
 39             ctx.strokeStyle = "blue";
 40             ctx.moveTo(5, 300);
 41             ctx.lineTo(395, 300);
 42             ctx.stroke();
 43
 44             ctx.font = "20px Arial"
 45
 46             //在 y=300 以不同的 textBaseline 值放置每个单词
 47             ctx.textBaseline = "top";
 48             ctx.fillText("Top", 25, 300);
 49             ctx.textBaseline = "bottom";
 50             ctx.fillText("Bottom", 50, 300);
 51             ctx.textBaseline = "middle";
 52             ctx.fillText("Middle", 120, 300);
 53             ctx.textBaseline = "alphabetic";
 54             ctx.fillText("Alphabetic", 200, 300);
 55             ctx.textBaseline = "hanging";
 56             ctx.fillText("Hanging", 290, 300);
 57
 58         }
 59
 60         function wrapText() {
 61
 62             var canvas = document.getElementById("myCanvas");
 63             var context = canvas.getContext("2d");
 64             var maxWidth = 300;
 65             var lineHeight = 25;
 66             var x = (canvas.width - maxWidth) / 2;
 67             var y = 400;
 68             var text = "All the world ‘s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.";
 69             context.font = "16pt Calibri";
 70             //context.fillStyle = "#333";
 71
 72             // 创建渐变
 73             var gradient = context.createLinearGradient(0, 0, canvas.width, 0);
 74             gradient.addColorStop("0", "magenta");
 75             gradient.addColorStop("0.5", "blue");
 76             gradient.addColorStop("1.0", "red");
 77             // 用渐变填色
 78             context.fillStyle = gradient;
 79             context.textBaseline = ‘bottom‘;
 80
 81
 82             var words = text.split(" ");
 83             var line = "";
 84             for (var n = 0; n < words.length; n++) {
 85                 var testLine = line + words[n] + " ";
 86                 var metrics = context.measureText(testLine);
 87                 var testWidth = metrics.width;
 88                 if (testWidth > maxWidth) {//大于最大长度 则将当前行输出,然后换行(y增加)并将换行后的首字母赋值给line
 89                     context.fillText(line, x, y);
 90                     line = words[n] + " ";
 91                     y += lineHeight;
 92                 } else {
 93                     line = testLine;
 94                 }
 95             }
 96             context.fillText(line, x, y);//最后一行
 97         }
 98     </script>
 99 </head>
100 <body>
101     <canvas id="myCanvas" width="1000" height="600"></canvas>
102 </body>
103 </html>

效果如图(由于LZ截图问题,设置的居中在图中是不居中的):

小结

本篇介绍了线、路径、渐变和文本,下篇将介绍阴影、状态储存和恢复等。

由于LZ现在不如之前清闲了,可能会耽误进度,但是我会尽量坚持写完该系列,谢谢支持。

时间: 2024-10-21 18:52:11

HTML5简单入门系列的相关文章

HTML5简单入门系列(五)

前言 本篇将讲述HTML5的服务器发送事件(server-sent event) Server-Sent 事件 Server-Sent 事件是单向消息传递,指的是网页自动获取来自服务器的更新. 以前的做法是网页不断的询问(向服务器发送请求)是否有可用的更新.通过服务器反馈之后,获得更新. 轮训方案 我们使用上篇HTML5简单入门系列(四)web worker的技术简单实现一下该轮训方案,主动向服务器询问是否有更新. 由于web worker不能访问document等对象,是不能和jQuery连用

HTML5简单入门系列(六)

前言 之前几篇已经将HTML5的主要新增元素和特性简单介绍完毕,LZ一直在犹豫还要不要把其他元素也写出来,因为其实没什么东西可以写,就是自己用到时看一下就行.不过为了入门系列的完整,犹豫再三,还是决定简单写一下其他元素(看到其他深入的HTML5,LZ就不写到这里了,因为LZ也没掌握,这里有篇深入剖析HTML5,各位可以看看). HTML5 新增元素介绍 input类型 新增的输入类型元素有: email url number range Date pickers (date, month, we

HTML5简单入门系列(九)

前言 上篇本来应该就是最后一篇了,但是楼主总觉得没有写上一个简单应用,不算是完整的学习系列.所以增加一篇关于动画的应用,对一个开源动画的介绍(很基础,非楼主原创). 本篇介绍一个基于Canvas的发光加载动画(这里可下载源码).算是对之前系列的各个知识点的一个总结吧. 我们先看看最终的效果截图: 新建一个html和一个js文件 html文件引入该js,并加了一个背景黑色,大体如下这样: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <

HTML5简单入门系列(三)

前言 本篇介绍HTML5支持的Web存储(Web Storage)和HTML 5 应用程序缓存. 客户端存储数据介绍 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 sessionStorage存储的数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁.因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储. localStorag

HTML5简单入门系列(一)

前言 随着HTML5的流行,LZ作为一个web开发者,也决定学习一下前端前沿技术. HTML5 是下一代的HTML,它将成为 HTML.XHTML 以及 HTML DOM 的新标准.它是W3C( World Wide Web Consortium)和WHATWG(Web Hypertext Application Technology Working Group)合作的结果,在2014年10月29日宣布完成.他们为 HTML5 建立的一些规则:1.新特性应该基于 HTML.CSS.DOM 以及

HTML5简单入门系列(四)

前言 今天这篇内容主要讲述HTML 5 Web Worker(一种支持前端js多线程的技术). 工作线程(Web Worker) web worker介绍 W3C 在 HTML5 的规范中提出了工作线程(Web Worker)的概念,工作线程允许开发人员编写能够长时间运行而不被用户所中断的后台程序, 去执行事务或者逻辑,并同时保证页面对用户的及时响应.工作线程的出现使得在 Web 页面中进行多线程编程成为可能.众所周知,传统页面中(HTML5 之前)的 JavaScript 的运行都是以单线程的

03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素

Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 2.功能元素 1.hgroup 对网页或区段(section)的标题进行组合 2.figure <figure> 标签规定独立的流内容(图像.图表.照片.代码等等). figure 元素的内容应该与主内容相关,但如果被删除,则不应对文档流产生影响. Figcaption figure的标题 一般格式: <figure> <figcap

04. Web大前端时代之:HTML5+CSS3入门系列~HTML5 表单

Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html ? 待续.... 04. Web大前端时代之:HTML5+CSS3入门系列~HTML5 表单

06. Web大前端时代之:HTML5+CSS3入门系列~HTML5 画布

Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html