进修 HTML5 Canvas 这一篇文章就够了

发布日期:2019-07-23 19:42:47 阅读数: 802次 来源: 作者:

一、canvas 简介

<canvas>HTML5 新增的,一个能够利用脚本(凡是为 JavaScript) 在此中绘制图像的 HTML 元素。它能够用来制造照片集或者制造简单(也不是那么简单)的动画,以至能够进行及时视频处置和衬着。

​它最后由苹果内部利用本身 MacOS X WebKit 推出,供使用法式利用像仪表盘的构件和 Safari 浏览器利用。后来,有人通过 Gecko 内核的浏览器 (特别是 MozillaFirefox),OperaChrome 和超文本收集使用手艺工作组建议为下一代的收集手艺利用该元素。

Canvas 是由 HTML 代码共同高度和宽度属性而定义出的可绘制区域。JavaScript 代码能够拜候该区域,雷同于其他通用的二维 API,通过一套完整的画图函数来动态生成图形。

​ Mozilla 法式从 Gecko 1.8 (Firefox 1.5) 起头支撑 <canvas>, Internet Explorer 从 IE9 起头 <canvas> 。Chrome 和 Opera 9+ 也支撑 <canvas>


二、Canvas根基利用

<canvas id="tutorial" width="300" height="300"></canvas>

2.1 <canvas> 元素

<canvas> 看起来和 <img> 标签一样,只是 <canvas> 只要两个可选的属性 width、heigth 属性,而没有 src、alt 属性。

​若是不给 <canvas> 设置 widht、height 属性时,则默认 width为300、height 为 150,单元都是 px。也能够利用 css 属性来设置宽高,可是如宽高属性和初始比例纷歧致,他会呈现扭曲。所以,建议永久不要利用 css 属性来设置 <canvas> 的宽高。

替代内容

​因为某些较老的浏览器(特别是 IE9 之前的 IE 浏览器)或者浏览器不支撑 HTML 元素 <canvas>,在这些浏览器上你该当老是能展现替代内容。

​支撑 <canvas> 的浏览器会只衬着 <canvas> 标签,而忽略此中的替代内容。不支撑 <canvas> 的浏览器则 会间接衬着替代内容。

用文本替代:

<canvas>
    你的浏览器不支撑 canvas,请升级你的浏览器。
</canvas>

<img> 替代:

<canvas>
    <img src="./美女.jpg" alt="亚博手机app"> 
</canvas>

竣事标签 </canvas> 不成省略。

<img> 元素分歧,<canvas> 元素需要竣事标签(</canvas>)。若是竣事标签不具有,则文档的其余部门会被认为是替代内容,将不会显示出来。

2.2 衬着上下文(Thre Rending Context)

<canvas> 会建立一个固定大小的画布,会公开一个或多个衬着上下文(画笔),利用衬着上下文来绘制和处置要展现的内容。

​ 我们重点研究 2D 衬着上下文。 其他的上下文我们暂不研究,好比, WebGL 利用了基于 OpenGL ES的3D 上下文 ("experimental-webgl") 。

var canvas = document.getElementById('tutorial');
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');

2.3 检测支撑性

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

if (canvas.getContext){
  var ctx = canvas.getContext('2d');
  // drawing code here
} else {
  // canvas-unsupported code here
}

2.4 代码模板

实例

<canvas id="tutorial" width="300" height="300"></canvas> <script type="text/javascript"> function draw(){ var canvas = document.getElementById('tutorial'); if(!canvas.getContext) return; var ctx = canvas.getContext("2d"); //起头代码 } draw(); </script>

测验考试一下 »

2.5 一个简单的例子

以下实例绘制两个长方形:

实例

<canvas id="tutorial" width="300" height="300"></canvas> <script type="text/javascript"> function draw(){ var canvas = document.getElementById('tutorial'); if(!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.fillStyle = "rgb(200,0,0)"; //绘制矩形 ctx.fillRect (10, 10, 55, 50); ctx.fillStyle = "rgba(0, 0, 200, 0.5)"; ctx.fillRect (30, 30, 55, 50); } draw(); </script>

测验考试一下 »

三、绘制外形

3.1 栅格 (grid) 和坐标空间

​如下图所示,canvas 元素默认被网格所笼盖。凡是来说网格中的一个单位相当于 canvas 元素中的一像素。栅格的起点为左上角,坐标为 (0,0) 。所有元素的位置都相对于原点来定位。所以图中蓝色方形左上角的坐标为距离右边(X 轴)x 像素,距离上边(Y 轴)y 像素,坐标为 (x,y)。

​后面我们会涉和到坐标原点的平移、网格的扭转以和缩放等。

3.2 绘制矩形

<canvas> 只支撑一种原生的图形绘制:矩形。所有其他图形都至多需要生成一种路径 (path)。不外,我们具有浩繁路径生成的方式让复杂图形的绘制成为了可能。

canvast 供给了三种方式绘制矩形:

  • 1、fillRect(x, y, width, height):绘制一个填充的矩形。
  • 2、strokeRect(x, y, width, height):绘制一个矩形的边框。
  • 3、clearRect(x, y, widh, height):断根指定的矩形区域,然后这块区域会变的完全通明。

申明:这 3 个方式具有不异的参数。

  • x, y:指的是矩形的左上角的坐标。(相对于canvas的坐标原点)
  • width, height:指的是绘制的矩形的宽和高。
function draw(){ var canvas = document.getElementById('tutorial'); if(!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.fillRect(10, 10, 100, 50); // 绘制矩形,填充的默认颜色为黑色 ctx.strokeRect(10, 70, 100, 50); // 绘制矩形边框 } draw();

ctx.clearRect(15, 15, 50, 25);


四、绘制路径 (path)

图形的根基元素是路径。

路径是通过分歧颜色和宽度的线段或曲线相连构成的分歧外形的点的调集。

一个路径,以至一个子路径,都是闭合的。

利用路径绘制图形需要一些额外的步调:

  1. 建立路径起始点
  2. 挪用绘制方式去绘制出路径
  3. 把路径封锁
  4. 一旦路径生成,通过描边或填充路径区域来衬着图形。

下面是需要用到的方式:

  1. beginPath()

    新建一条路径,路径一旦建立成功,图形绘制号令被指向到路径上生成路径

  2. moveTo(x, y)

    把画笔挪动到指定的坐标(x, y)。相当于设置路径的起始点坐标。

  3. closePath()

    闭合路径之后,图形绘制号令又从头指向到上下文中

  4. stroke()

    通过线条来绘制图形轮廓

  5. fill()

    通过填充路径的内容区域生成实心的图形

4.1 绘制线段

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); //新建一条path ctx.moveTo(50, 50); //把画笔挪动到指定的坐标 ctx.lineTo(200, 50); //绘制一条从当前位置到指定坐标(200, 50)的直线. //闭合路径。会拉一条从当前点到path起始点的直线。若是当前点与起始点重合,则什么都不做 ctx.closePath(); ctx.stroke(); //绘制路径。 } draw();

4.2 绘制三角形边框

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); //虽然我们只绘制了两条线段,可是closePath会closePath,仍然是一个3角形 ctx.stroke(); //描边。stroke不会主动closePath() } draw();

4.3 填充三角形

亚博function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.fill(); //填充闭合区域。若是path没有闭合,则fill()会主动闭合路径。 } draw();

4.4 绘制圆弧

有两个方式能够绘制圆弧:

1、arc(x, y, r, startAngle, endAngle, anticlockwise): 以(x, y)为圆心,以r为半径,从 startAngle弧度起头到endAngle弧度竣事。anticlosewise是布尔值,true暗示逆时针,false暗示顺时针(默认是顺时针)。

留意:

  1. 这里的度数都是弧度。

  2. 0 弧度是指的 x 轴正方形。

    radians=(Math.PI/180)*degrees   //角度转换成弧度

2、arcTo(x1, y1, x2, y2, radius): 按照给定的节制点和半径画一段圆弧,最初再以直线毗连两个节制点。

圆弧案例 1

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(50, 50, 40, 0, Math.PI / 2, false); ctx.stroke(); } draw();

圆弧案例 2

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(50, 50, 40, 0, Math.PI / 2, false); ctx.stroke(); ctx.beginPath(); ctx.arc(150, 50, 40, 0, -Math.PI / 2, true); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.arc(50, 150, 40, -Math.PI / 2, Math.PI / 2, false); ctx.fill(); ctx.beginPath(); ctx.arc(150, 150, 40, 0, Math.PI, false); ctx.fill(); } draw();

圆弧案例 3

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(50, 50); //参数1、2:节制点1坐标 参数3、4:节制点2坐标 参数4:圆弧半径 ctx.arcTo(200, 50, 200, 200, 100); ctx.lineTo(200, 200) ctx.stroke(); ctx.beginPath(); ctx.rect(50, 50, 10, 10); ctx.rect(200, 50, 10, 10) ctx.rect(200, 200, 10, 10) ctx.fill() } draw();

arcTo 方式的申明:

这个方式能够如许理解。绘制的弧形是由两条切线所决定。

第 1 条切线:起始点和节制点1决定的直线。

第 2 条切线:节制点1 和节制点2决定的直线。

​其实绘制的圆弧就是与这两条直线相切的圆弧。

4.5 绘制贝塞尔曲线

4.5.1 什么是贝塞尔曲线

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是使用于二维图形使用法式的数学曲线。

一般的矢量图形软件通过它来切确画出曲线,贝兹曲线由线段与节点构成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在画图东西上看到的钢笔东西就是来做这种矢量曲线的。

贝塞尔曲线是计较机图形学中相当主要的参数曲线,在一些比力成熟的位图软件中也有贝塞尔曲线东西如 PhotoShop 等。在 Flash4 中还没有完整的曲线东西,而在 Flash5 里面曾经供给出贝塞尔曲线东西。

贝塞尔曲线于 1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所普遍颁发,他使用贝塞尔曲线来为汽车的主体进行设想。贝塞尔曲线最后由Paul de Casteljau 于 1959 年使用 de Casteljau 演算法开辟,以不变数值的方式求出贝兹曲线。

一次贝塞尔曲线其实是一条直线

二次贝塞尔曲线

三次贝塞尔曲线

4.5.2 绘制贝塞尔曲线

绘制二次贝塞尔曲线:

quadraticCurveTo(cp1x, cp1y, x, y)

申明:

  • ​ 参数 1 和 2:节制点坐标
  • ​ 参数 3 和 4:竣事点坐标
function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(10, 200); //起始点 var cp1x = 40, cp1y = 100; //节制点 var x = 200, y = 200; // 竣事点 //绘制二次贝塞尔曲线 ctx.quadraticCurveTo(cp1x, cp1y, x, y); ctx.stroke(); ctx.beginPath(); ctx.rect(10, 200, 10, 10); ctx.rect(cp1x, cp1y, 10, 10); ctx.rect(x, y, 10, 10); ctx.fill(); } draw();

绘制三次贝塞尔曲线:

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

申明:

  • ​ 参数 1 和 2:节制点 1 的坐标
  • ​ 参数 3 和 4:节制点 2 的坐标
  • ​ 参数 5 和 6:竣事点的坐标
function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(40, 200); //起始点 var cp1x = 20, cp1y = 100; //节制点1 var cp2x = 100, cp2y = 120; //节制点2 var x = 200, y = 200; // 竣事点 //绘制二次贝塞尔曲线 ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); ctx.stroke(); ctx.beginPath(); ctx.rect(40, 200, 10, 10); ctx.rect(cp1x, cp1y, 10, 10); ctx.rect(cp2x, cp2y, 10, 10); ctx.rect(x, y, 10, 10); ctx.fill(); } draw();


五、添加样式和颜色

​ 在前面的绘制矩形章节中,只用到了默认的线条和颜色。

​ 若是想要给图形上色,有两个主要的属性能够做到。

  1. fillStyle = color 设置图形的填充颜色

  2. strokeStyle = color 设置图形轮廓的颜色

备注:

  • 1. color 能够是暗示 css 颜色值的字符串、渐变对象或者图案对象。
  • 2. 默认环境下,线条和填充颜色都是黑色。
  • 3. 一旦您设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。若是你要给每个图形上分歧的颜色,你需要从头设置 fillStyle 或 strokeStyle 的值。

fillStyle

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); for (var i = 0; i < 6; i++){ for (var j = 0; j < 6; j++){ ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ',' + Math.floor(255 - 42.5 * j) + ',0)'; ctx.fillRect(j * 50, i * 50, 50, 50); } } } draw();

strokeStyle

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); for 亚博手机app