HTML5 Canvas标识应用收录

日期:2021-02-26 类型:科技新闻 

关键词:微信公众号平台小程序,微信打分小程序,小程序发布,小程序大全,微信小程序编程

 1、基础定义

甚么是Canvas

<canvas> 是1个新的 HTML 元素,这个元素在 HTML5  中被界定。这个元素一般能够被用来在 HTML 网页页面中根据 JavaScript 开展绘图图型、生成图象这些实际操作,还可以用来做1些动漫。自然,现阶段 HTML5 标准还在文稿环节,宣布公布或许要直到2010年,但是如今早已有很多访问器早已适用了一部分 HTML5 标准。现阶段适用 canvas 元素的访问器有 Firefox 3+、Safari 4、Chrome 2.0+ 等,因而,在运作本页中的事例时,请保证你应用的是上述访问器之1。

虽然在 Mozilla  早已有很多有关 Canvas 的实例教程,我還是决策把自身的学习培训全过程纪录下来。假如感觉我写的不足搞清楚,那末你能够在参照材料中寻找 Mozilla 网站上 Canvas 实例教程的连接。

此外,能够在这里 寻找1些趣味的 Canvas 示例

刚开始应用 Canvas

应用 Canvas 很简易,与应用别的 HTML 元素1样,只必须在网页页面中加上1个 <canvas> 标识便可:

编码以下:

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



自然,这样只是简易的建立了1个 Canvas 目标罢了,并沒有对它开展任何实际操作,这个情况下的 canvas 元素看上去与 div 元素是没甚么差别的,在网页页面上甚么都看不出来:)
此外,canvas 元素的尺寸能够根据 width 与 height 特性来特定,这与 img 元素有点类似。

Canvas 的关键:Context
前面说到能够根据 JavaScript 来实际操作 Canvas 目标来开展绘图图型、生成图象等实际操作,这些实际操作其实不是根据 Canvas 目标自身来开展的,而是根据 Canvas 目标的1个方式 getContext 获得 Canvas 实际操作左右文来开展。也便是说,在后边大家应用 Canvas 目标的全过程中,全是与 Canvas 目标的 Context 打交道,而 Canvas 目标自身能够用来获得 Canvas 目标的尺寸等信息内容。
要获得 Canvas 目标的 Context 很简易,立即启用 canvas 元素的 getContext 方式便可,在启用的情况下必须传送1个 Context 种类主要参数,现阶段能够用的而且是唯1能够用的种类值便是 2d:

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

Firefox 3.0.x 的难堪

Firefox 3.0.x 尽管适用了 canvas 元素,可是并沒有彻底依照标准来完成,标准中的 fillText、 measureText 两个方式在 Firefox 3.0.x 中被几个 Firefox 独有的方式替代,因而在 Firefox 3.0.x 中应用 Canvas 时必须先 fix 这个几个方式在不一样访问器中的区别。

下面这编码取自 Mozilla Bespin  新项目,它调整了 Firefox 3.0.x 中 Canvas 的 Context 目标与 HTML5 标准不1致的地区:

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

留意:到 Opera 9.5 为止,Opera 还不适用 HTML5 标准中 Canvas 目标的 fillText 和其有关方式和特性。

Hello, Canvas!

在对 Canvas 开展了1些基本掌握后,刚开始来写大家的第1个 Canvas 程序流程,出名的 HelloWorld 的又1个支系“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 中显示信息文本,它能够接纳4个主要参数,在其中最终1个是可选的:

void fillText(in DOMString text, in float x, in float y, [Optional] in float maxWidth);

在其中 maxWidth 表明显示信息文本时最大的宽度,能够避免文本外溢,但是我在检测中发如今 Firefox 与 Chomre 中特定了 maxWidth 时也沒有任何实际效果。

在应用 fillText 方式以前,能够根据设定 Context 的 font 特性来调剂显示信息文本的字体样式,在上面的示例中我应用了“20pt Arial”来做为显示信息文本的字体样式,你能够自身设定不一样的值看来实际的实际效果。

2、相对路径

图型的基本 - 相对路径

在 Canvas 中,全部基础图型全是以相对路径为基本的,也便是说,大家在启用 2dContext 的 lineTo、rect 等方式时,实际上便是往早已的 context 相对路径结合中再加上1些相对路径点,在最终应用 fill 或 stroke 方式开展绘图时,全是根据这些相对路径点来开展填充或画线。

在每次刚开始绘图相对路径前,都应当应用 context.beginPath() 方式来告知 Context 目标刚开始绘图1个新的相对路径,不然接下来绘图的相对路径会与以前绘图的相对路径叠加,在填充或画边框时就会出現难题。在绘图进行相对路径后,能够立即应用 context.closePath() 方式来关掉相对路径,或手动式关掉相对路径。此外,假如在填充时相对路径沒有关掉,那末 Context 会全自动启用 closePath 方式将相对路径关掉。

基础相对路径方式

1. beginPath, closePath

这两个方式在前面早已详细介绍过,各自用来通告 Context 刚开始1个新的相对路径和关掉当今的相对路径。

在 Canvas 中应用相对路径时,应当要维持1个优良的习惯性,每次刚开始绘图相对路径前都要启用1次 beginPath 方式,不然画出来的实际效果不好看不说,还会比较严重危害特性。

在下面这张图中,左侧的图型在每次绘图矩形框前都启用了1次 beginPath 来消除以前的相对路径并再次刚开始绘图新的相对路径,然后面的图型则就只在绘图全部图型前启用了1次 beginPath 来消除相对路径,因而,尽管这里是应用的边框色是 #666,可是右侧的图型色调比左侧的深1些,由于每次应用 stroke 绘图边框时,会把以前的相对路径再度绘图1遍,叠加起来色调就比原先深1些。

<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 的话,由于每次绘图都要将以前的相对路径再次绘图1遍,这时候特性会以指数值降低。

因而,除非有独特必须,每次刚开始绘图相对路径前都要启用 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>


void moveTo(in float x, in float y);

在 Canvas 中绘图相对路径,1般是不必须特定起始点的,默认设置的起始点便是上1次绘图相对路径的终点站,因而,假如必须特定起始点的话,就必须应用 moveTo 方式来特定要挪动到的部位。

void lineTo(in float x, in float y);

lineTo 方式则是绘图1条立即相对路径到特定的部位。在启用完 lineTo 方式后,Context 內部的绘图起始点会挪动到平行线的终点站。

void rect(in float x, in float y, in float w, in float h);

rect 方式用来绘图1个矩形框相对路径,根据主要参数特定左上角部位和宽和高。在启用 rect 后,Context 的绘图起始点会挪动到 rect 绘图的矩形框的左上角。

rect 方式与后边要详细介绍的 arc 方式与别的相对路径方式有1点不一样,它们是应用主要参数特定起始点的,而并不是应用 Context 內部维护保养的起始点。

3. 曲线图 arcTo, arc, quadraticCurveTo, bezierCurveTo

void arcTo(in float x1, in float y1, in float x2, in float y2, in float radius);

依照 WHATWG 文本文档的表明,这个方式是画1个与两条射线相切的的圆弧,两条射线在其中1条为穿过 Context 绘图起始点,终点站为 (x1, y1),此外1条为穿过 (x2, y2),终点站为 (x1, y1),这条圆弧为最少的与这两条射线相切的圆弧。在启用完 arcTo 方式后,将 圆弧与 射线 (x1, y1)-(x2, y2) 的切点加上到当今相对路径中,作为下一次绘图的起始点。

在检测中发现,Firefox 和 Opera 现阶段对这个方式的适用其实不好,仅有 Chrome 和 Safari 4 能绘图出正确的相对路径。

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

void arc(in float x, in float y, in float radius, in float startAngle, in float endAngle, in boolean anticlockwise);

arc 方式用来绘图1段圆弧相对路径,根据圆心部位、起止弧度、停止弧度来特定圆弧的部位和尺寸,这个方式也 依靠于 Context 维护保养的绘图起始点。而在画圆弧时的转动方位则由最终1个主要参数 anticlockwise 来特定,假如为 true 便是逆时针,false 则为顺时针。

void quadraticCurveTo(in float cpx, in float cpy, in float x, in float y);

quadraticCurveTo 方式用来绘图2次样条曲线图相对路径,主要参数中 cpx 与 cpy 特定操纵点的部位,x 和 y 特定终点站的部位,起始点则是由 Context 维护保养的绘图起始点。

void bezierCurveTo(in float cp1x, in float cp1y, in float cp2x, in float cp2y, in float x, in float y);

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 设定1个剪辑地区,在启用 clip 方式以后的编码只对这个设置的剪辑地区合理,不容易危害别的地区,这个方式在要开展部分升级时很有效。默认设置状况下,剪辑地区是1个左上角在 (0, 0),宽和高各自等于 Canvas 元素的宽和高的矩形框。

在画这个图时,尽管两次全是应用 fillRect(0, 0, 100, 100) 填充了1个 100x100 尺寸矩形框,可是显示信息的結果确是第2次填充的只是正中间的1小块,这是由于在两次填充之间应用 clip 方式设置了剪辑地区,这样第2次填充时只会危害到所设置的正中间那1小一部分地区。

<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

这3个方式其实不是相对路径方式,而是用来立即解决 Canvas 上的內容,非常于 Canvas 的情况,启用这3个方式也不容易危害 Context 制图的起始点。

要消除 Canvas 上的全部內容时,能够立即启用 context.clearRect(0, 0, width, height) 来立即消除,而不必须应用相对路径方式绘图1个与 Canvas 同样尺寸的矩形框相对路径再应用 fill 方式去消除。

结语

根据 Canvas 的相对路径方式,可使用 Canvas 解决1些简易的矢量图型,这样在放缩时也不容易失真。但是 Canvas 的相对路径方式也并不是很强劲,最少连个椭圆的相对路径都沒有……

参照材料
1. The Canvas Element, WHATWG