Canvas 超全教程

2019-10-09  本文已影响0人  Adoins

一、简介

<canvas>是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素.例如,它可以用于绘制图表、制作图片构图或者制作简单的(以及不那么简单的)动画.

<canvas> 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,随后被各个浏览器实现。如今,所有主流的浏览器都支持它。

二、兼容性处理

1. 替换文本

<canvas>元素与<img>标签的不同之处在于,就像<video><audio>,或者<picture>元素一样,很容易定义一些替代内容。由于某些较老的浏览器(尤其是IE9之前的IE浏览器)或者文本浏览器不支持HTML元素"canvas",在这些浏览器上你应该总是能展示替代内容。

这非常简单:我们只是在<canvas>标签中提供了替换内容。不支持<canvas>的浏览器将会忽略容器并在其中渲染后备内容。而支持<canvas>的浏览器将会忽略在容器中包含的内容,并且只是正常渲染canvas。

举个例子,我们可以提供对canvas内容的文字描述或者是提供动态生成内容相对应的静态图片,如下所示:

<canvas id="stockGraph" width="150" height="150">
  current stock price: $3.15 +0.15
</canvas>

<canvas id="clock" width="150" height="150">
  <img src="images/clock.png" width="150" height="150" alt=""/>
</canvas>

2. 检查支持性

替换内容是用于在不支持 <canvas> 标签的浏览器中展示的。通过简单的测试getContext()方法的存在,脚本可以检查编程支持性。上面的代码片段现在变成了这个样子:

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

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

三、模版骨架

这里的是一个最简单的模板,我们之后就可以把它作为之后的例子的起点。

<html>
  <head>
    <title>Canvas tutorial</title>
    <style type="text/css">
      canvas { border: 1px solid black; }
    </style>
  </head>
  <body onload="draw();">
    <canvas id="tutorial" width="150" height="150"></canvas>

    <script type="text/javascript">
      function draw(){
        var canvas = document.getElementById('tutorial');
        if (canvas.getContext){
          var ctx = canvas.getContext('2d');
          // drawing code here
        } else {
          // canvas-unsupported code here
        }
      }
    </script>
  </body>
</html>

](https://img.haomeiwen.com/i4573742/5cd1f3cb46481846.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

上面的脚本中包含一个叫做draw()的函数,当页面加载结束的时候就会执行这个函数。通过使用在文档上加载事件来完成。只要页面加载结束,这个函数,或者像是这个的,同样可以使用 window.setTimeout(), window.setInterval(),或者其他任何事件处理程序来调用。

四、绘制形状

1. 栅格

在我们开始画图之前,我们需要了解一下画布栅格(canvas grid)以及坐标空间。上一页中的HTML模板中有个宽150px, 高150px的canvas元素。如右图所示,canvas元素默认被网格所覆盖。通常来说网格中的一个单元相当于canvas元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X轴)x像素,距离上边(Y轴)y像素(坐标为(x,y))。在课程的最后我们会平移原点到不同的坐标上,旋转网格以及缩放。现在我们还是使用原来的设置。

image

2. 渲染上下文(The rendering context)

<canvas> 元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。我们将会将注意力放在2D渲染上下文中。其他种类的上下文也许提供了不同种类的渲染方式;比如, WebGL 使用了基于OpenGL ES的3D上下文 ("experimental-webgl") 。
canvas起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。<canvas> 元素有一个叫做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()只有一个参数,上下文的格式。对于2D图像而言,如本教程,你可以使用 CanvasRenderingContext2D。

var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');

3. 绘制矩形

不同于SVG,HTML中的元素canvas只支持一种原生的图形绘制:矩形。所有其他的图形的绘制都至少需要生成一条路径。不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能。

4. 绘制路径

图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  1. 首先,你需要创建路径起始点。
  2. 然后你使用画图命令去画出路径。
  3. 之后你把路径封闭。
  4. 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

以下是所要用到的函数:

注:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。

4. 移动笔触

moveTo(x, y):将笔触移动到指定的坐标x以及y上。

5. 线

[lineTo(x, y)](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/lineTo):绘制一条从当前位置到指定x以及y位置的直线。

6. 圆弧

绘制圆弧或者圆,我们使用arc()方法。当然可以使用arcTo(),不过这个的实现并不是那么的可靠,所以我们这里不作介绍。

注:arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式: 弧度=(Math.PI/180)*角度。

7. 二次贝塞尔曲线及三次贝塞尔曲线

下边的图能够很好的描述两者的关系,二次贝塞尔曲线有一个开始点(蓝色)、一个结束点(蓝色)以及一个控制点(红色),而三次贝塞尔曲线有两个控制点。

参数x、y在这两个方法中都是结束点坐标。cp1x,cp1y为坐标中的第一个控制点,cp2x,cp2y为坐标中的第二个控制点。

image

8. Path 2D 对象

所有的路径方法比如moveTo, rect, arc或quadraticCurveTo等,如我们前面见过的,都可以在Path2D中使用。

Path2D API 添加了 addPath作为将path结合起来的方法。当你想要从几个元素中来创建对象时,这将会很实用。比如:

五、添加样式和色彩

1. 色彩 Colors

ctx.fillStyle = "orange";
  ctx.fillStyle = "#FFA500";
  ctx.fillStyle = "rgb(255,165,0)";
  ctx.fillStyle = "rgba(255,165,0,1)";

注: 一旦您设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,你需要重新设置 fillStyle 或 strokeStyle 的值。

2. 透明度 Transparency

// 指定透明颜色,用于描边和填充样式
ctx.strokeStyle = "rgba(255,0,0,0.5)";
ctx.fillStyle = "rgba(255,0,0,0.5)";

3. 线型

4. 渐变 Gradients

创建出 canvasGradient 对象后,我们就可以用 addColorStop 方法给它上色了。

var lineargradient = ctx.createLinearGradient(0,0,150,150);
lineargradient.addColorStop(0,'white');
lineargradient.addColorStop(1,'black');

5. 图案样式 Patterns

注意: 用 canvas 对象作为 Image 参数在 Firefox 1.5 (Gecko 1.8) 中是无效的。

var img = new Image();
img.src = 'someimage.png';
var ptrn = ctx.createPattern(img,'repeat');

6. 阴影 Shadows

7. Canvas 填充规则

当我们用到 fill(或者 [clip](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/clip)[isPointinPath](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/isPointInPath) )你可以选择一个填充规则,该填充规则根据某处在路径的外面或者里面来决定该处是否被填充,这对于自己与自己路径相交或者路径被嵌套的时候是有用的。
两个可能的值:

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d'); 
  ctx.beginPath(); 
  ctx.arc(50, 50, 30, 0, Math.PI*2, true);
  ctx.arc(50, 50, 15, 0, Math.PI*2, true);
  ctx.fill("evenodd");
}
image

六、绘制文本

// 下面的代码段将展示如何测量文本来获得它的宽度:
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var text = ctx.measureText("foo"); // TextMetrics object
  text.width; // 16;
}

七、使用图片

引入图像到canvas里需要以下两步基本操作:

  1. 获得一个指向[HTMLImageElement](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/HTMLImageElement)的对象或者另一个canvas元素的引用作为源,也可以通过提供一个URL的方式来使用图片(参见例子
  2. 使用drawImage()函数将图片绘制到画布上

1. 获得需要绘制的图片

var img = new Image();   // 创建img元素
img.onload = function(){
  // 执行drawImage语句
}
img.src = 'myImage.png'; // 设置图片源地址

(5) 通过 data: url 方式嵌入图像
我们还可以通过 data:url 方式来引用图像。Data urls 允许用一串 Base64 编码的字符串的方式来定义一个图片。

img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';

(6) 使用视频帧

function getMyVideo() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    return document.getElementById('myvideo');
  }
}

2. 绘制图片

SVG图像必须在 <svg> 根指定元素的宽度和高度。

image

3. 控制图像的缩放行为

Gecko 1.9.2 引入了 mozImageSmoothingEnabled 属性,值为 false 时,图像不会平滑地缩放。默认是 true

cx.mozImageSmoothingEnabled = false;

八、变形

1. 状态的保存和恢复

2. 移动

3. 旋转

4. 缩放

5. 变形

m11 m21 dx
m12 m22 dy
0   0   1

如果任意一个参数是无限大,变形矩阵也必须被标记为无限大,否则会抛出异常。

这个函数的参数各自代表如下:

m11:水平方向的缩放

m12:水平方向的倾斜偏移

m21:竖直方向的倾斜偏移

m22:竖直方向的缩放

dx:水平方向的移动

dy:竖直方向的移动

九、组合

之前的例子里面,我们总是将一个图形画在另一个之上,对于其他更多的情况,仅仅这样是远远不够的。比如,对合成的图形来说,绘制顺序会有限制。不过,我们可以利用 globalCompositeOperation 属性来改变这种状况。此外, clip属性允许我们隐藏不想看到的部分图形。

1. [globalCompositeOperation](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Compositing%23globalCompositeOperation)

2. 裁切路径

裁切路径和普通的 canvas 图形差不多,不同的是它的作用是遮罩,用来隐藏不需要的部分。如右图所示。红边五角星就是裁切路径,所有在路径以外的部分都不会在 canvas 上绘制出来。

image

十、动画

1. 动画的基本步骤

(1)清空 canvas
除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法。
(2)保存 canvas 状态
如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
(3)绘制动画图形(animated shapes)
这一步才是重绘动画帧。
(4)恢复 canvas 状态
如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

2. 操控动画

在 canvas 上绘制内容是用 canvas 提供的或者自定义的方法,而通常,我们仅仅在脚本执行结束后才能看见结果,比如说,在 for 循环里面做完成动画是不太可能的。

因此, 为了实现动画,我们需要一些可以定时执行重绘的方法。有两种方法可以实现这样的动画操控。首先可以通过 setInterval 和 setTimeout 方法来控制在设定的时间点上执行重绘。
(1)有安排的更新画布 Scheduled updates

十一、像素操作

1. ImageData 对象

根据行、列读取某像素点的R/G/B/A值的公式:

imageData.data[((行数-1)*imageData.width + (列数-1))*4 - 1 + 1/2/3/4];

2. 创建一个ImageData对象

3. 得到场景像素数据

var myImageData = ctx.getImageData(left, top, width, height);

这个方法会返回一个ImageData对象,它代表了画布区域的对象数据,此画布的四个角落分别表示为(left, top), (left + width, top), (left, top + height), 以及(left + width, top + height)四个点。这些坐标点被设定为画布坐标空间元素。

注:任何在画布以外的元素都会被返回成一个透明黑的ImageData对像。

3. 在场景中写入像素数据

ctx.putImageData(myImageData, dx, dy);: 你可以用putImageData()方法去对场景进行像素数据的写入。dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标。

4. 保存图片

十二、点击区域和无障碍访问

[<canvas>](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/HTML/Element/canvas) 标签只是一个位图,它并不提供任何已经绘制在上面的对象的信息。 canvas的内容不能像语义化的HTML一样暴露给一些协助工具。一般来说,你应该避免在交互型的网站或者App上使用canvas。接下来的内容能帮助你让canvas更加容易交互。

1. 内容兼容

<canvas> ... </canvas>标签里的内容被可以对一些不支持canvas的浏览器提供兼容。这对残疾用户设备也很有用(比如屏幕阅读器),这样它们就可以读取并解释DOM里的子节点。

2. ARIA 规则

Accessible Rich Internet Applications (ARIA) 定义了让Web内容和Web应用更容易被有身体缺陷的人获取的办法。你可以用ARIA属性来描述canvas元素的行为和存在目的。详情见ARIAARIA 技术
<canvas id="button" tabindex="0" role="button" aria-pressed="false" aria-label="Start game"></canvas>

3. 点击区域

判断鼠标坐标是否在canvas上一个特定区域里一直是个有待解决的问题。hit region API让你可以在canvas上定义一个区域,这让无障碍工具获取canvas上的交互内容成为可能。它能让你更容易地进行点击检测并把事件转发到DOM元素去。这个API有以下三个方法(都是实验性特性,请先在浏览器兼容表上确认再使用)。

你可以把一个点击区域添加到路径里并检测[MouseEvent.region](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/MouseEvent/region)属性来测试你的鼠标有没有点击这个区域,例:

<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.arc(70, 80, 10, 0, 2 * Math.PI, false);
ctx.fill();
ctx.addHitRegion({id: "circle"});

canvas.addEventListener("mousemove", function(event){
  if(event.region) {
    alert("hit region: " + event.region);
  }
});
</script>

// addHitRegion()方法也可以带一个control选项来指定把事件转发到哪个元素上(canvas里的元素)。
ctx.addHitRegion({control: element});

4. 焦点圈

十三、性能贴士

1. 在离屏canvas上预渲染相似的图形或重复的对象

如果你发现你的在每一帧里有好多复杂的画图运算,请考虑创建一个离屏canvas,将图像在这个画布上画一次(或者每当图像改变的时候画一次),然后在每帧上画出视线以外的这个画布。

2. 避免浮点数的坐标点,用整数取而代之

当你画一个没有整数坐标点的对象时会发生子像素渲染。浏览器为了达到抗锯齿的效果会做额外的运算。为了避免这种情况,请保证在你调用[drawImage()](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage)函数时,用[Math.floor()](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/floor)函数对所有的坐标点取整。

3. 不要在用drawImage时缩放图像

在离屏canvas中缓存图片的不同尺寸,而不要用[drawImage()](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage)去缩放它们。

4. 使用多层画布去画一个复杂的场景

5. 用CSS设置大的背景图

如果像大多数游戏那样,你有一张静态的背景图,用一个静态的[<div>](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/HTML/Element/div)元素,结合[background](https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/CSS/background) 特性,以及将它置于画布元素之后。这么做可以避免在每一帧在画布上绘制大图。

6. 用CSS transforms特性缩放画布

CSS transforms 特性由于调用GPU,因此更快捷。最好的情况是,不要将小画布放大,而是去将大画布缩小。例如Firefox系统,目标分辨率480 x 320 px。

var scaleX = canvas.width / window.innerWidth;
var scaleY = canvas.height / window.innerHeight;

var scaleToFit = Math.min(scaleX, scaleY);
var scaleToCover = Math.max(scaleX, scaleY);

stage.style.transformOrigin = '0 0'; //scale from top left
stage.style.transform = 'scale(' + scaleToFit + ')';

7. 关闭透明度

如果你的游戏使用画布而且不需要透明,当使用 [HTMLCanvasElement.getContext()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext "The HTMLCanvasElement.getContext() method returns a drawing context on the canvas, or null if the context identifier is not supported.") 创建一个绘图上下文时把 alpha 选项设置为 false 。这个选项可以帮助浏览器进行内部优化。
var ctx = canvas.getContext('2d', { alpha: false });

更多贴士

例子

1. 绘制两个长方形,一个带透明度

<html>
 <head>
  <script type="application/javascript">
    function draw() {
      var canvas = document.getElementById("canvas");
      if (canvas.getContext) {
        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);
      }
    }
  </script>
 </head>
 <body onload="draw();">
   <canvas id="canvas" width="150" height="150"></canvas>
 </body>
</html>
image

2. 绘制一个实心三角形

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.moveTo(75, 50);
    ctx.lineTo(100, 75);
    ctx.lineTo(100, 25);
    ctx.fill();
  }
}

[图片上传失败...(image-d3e7e0-1570584169259)]

3. 使用多个贝塞尔曲线

- 渲染对话气泡

function draw() {
 var canvas = document.getElementById('canvas');
 if (canvas.getContext) {
 var ctx = canvas.getContext('2d');

 // 二次贝塞尔曲线
 ctx.beginPath();
 ctx.moveTo(75,25);
 ctx.quadraticCurveTo(25,25,25,62.5);
 ctx.quadraticCurveTo(25,100,50,100);
 ctx.quadraticCurveTo(50,120,30,125);
 ctx.quadraticCurveTo(60,120,65,100);
 ctx.quadraticCurveTo(125,100,125,62.5);
 ctx.quadraticCurveTo(125,25,75,25);
 ctx.stroke();
  }
}
image

- 绘制心形

function draw() {
 var canvas = document.getElementById('canvas');
 if (canvas.getContext){
 var ctx = canvas.getContext('2d');

 //三次贝塞尔曲线
 ctx.beginPath();
 ctx.moveTo(75,40);
 ctx.bezierCurveTo(75,37,70,25,50,25);
 ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
 ctx.bezierCurveTo(20,80,40,102,75,120);
 ctx.bezierCurveTo(110,102,130,80,130,62.5);
 ctx.bezierCurveTo(130,62.5,130,25,100,25);
 ctx.bezierCurveTo(85,25,75,37,75,40);
 ctx.fill();
  }
}
image

4. 组合使用画游戏

function draw() {
 var canvas = document.getElementById('canvas');
 if (canvas.getContext){
 var ctx = canvas.getContext('2d');

 roundedRect(ctx,12,12,150,150,15);
 roundedRect(ctx,19,19,150,150,9);
 roundedRect(ctx,53,53,49,33,10);
 roundedRect(ctx,53,119,49,16,6);
 roundedRect(ctx,135,53,49,33,10);
 roundedRect(ctx,135,119,25,49,10);

 ctx.beginPath();
 ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false);
 ctx.lineTo(31,37);
 ctx.fill();

 for(var i=0;i<8;i++){
 ctx.fillRect(51+i*16,35,4,4);
 }

 for(i=0;i<6;i++){
 ctx.fillRect(115,51+i*16,4,4);
 }

 for(i=0;i<8;i++){
 ctx.fillRect(51+i*16,99,4,4);
 }

 ctx.beginPath();
 ctx.moveTo(83,116);
 ctx.lineTo(83,102);
 ctx.bezierCurveTo(83,94,89,88,97,88);
 ctx.bezierCurveTo(105,88,111,94,111,102);
 ctx.lineTo(111,116);
 ctx.lineTo(106.333,111.333);
 ctx.lineTo(101.666,116);
 ctx.lineTo(97,111.333);
 ctx.lineTo(92.333,116);
 ctx.lineTo(87.666,111.333);
 ctx.lineTo(83,116);
 ctx.fill();

 ctx.fillStyle = "white";
 ctx.beginPath();
 ctx.moveTo(91,96);
 ctx.bezierCurveTo(88,96,87,99,87,101);
 ctx.bezierCurveTo(87,103,88,106,91,106);
 ctx.bezierCurveTo(94,106,95,103,95,101);
 ctx.bezierCurveTo(95,99,94,96,91,96);
 ctx.moveTo(103,96);
 ctx.bezierCurveTo(100,96,99,99,99,101);
 ctx.bezierCurveTo(99,103,100,106,103,106);
 ctx.bezierCurveTo(106,106,107,103,107,101);
 ctx.bezierCurveTo(107,99,106,96,103,96);
 ctx.fill();

 ctx.fillStyle = "black";
 ctx.beginPath();
 ctx.arc(101,102,2,0,Math.PI*2,true);
 ctx.fill();

 ctx.beginPath();
 ctx.arc(89,102,2,0,Math.PI*2,true);
 ctx.fill();
 }
}

// 封装的一个用于绘制圆角矩形的函数.

function roundedRect(ctx,x,y,width,height,radius){
  ctx.beginPath();
  ctx.moveTo(x,y+radius);
  ctx.lineTo(x,y+height-radius);
  ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
  ctx.lineTo(x+width-radius,y+height);
  ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
  ctx.lineTo(x+width,y+radius);
  ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
  ctx.lineTo(x+radius,y);
  ctx.quadraticCurveTo(x,y,x,y+radius);
  ctx.stroke();
}
image

5. Path2D 示例

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');

    var rectangle = new Path2D();
    rectangle.rect(10, 10, 50, 50);

    var circle = new Path2D();
    circle.moveTo(125, 35);
    circle.arc(100, 35, 25, 0, 2 * Math.PI);

    ctx.stroke(rectangle);
    ctx.fill(circle);
  }
}
image

6. 文字阴影

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;
  ctx.shadowBlur = 2;
  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";

  ctx.font = "20px Times New Roman";
  ctx.fillStyle = "Black";
  ctx.fillText("Sample String", 5, 30);
}
image

注意点

  1. Canvas 的默认大小为300像素×150像素(宽×高,像素的单位是px)。但是,可以使用HTML的高度和宽度属性来自定义Canvas 的尺寸。
  2. 如果你绘制出来的图像是扭曲的, 尝试用width和height属性为<canvas>明确规定宽高,而不是使用CSS。
  3. <canvas>元素可以像任何一个普通的图像一样(有margin,border,background等等属性)被设计。然而,这些样式不会影响在canvas中的实际图像。我们将会在一个专门的章节里看到这是如何解决的。当开始时没有为canvas规定样式规则,其将会完全透明。
  4. 与 <img> 元素不同,<canvas> 元素需要结束标签(</canvas>)。如果结束标签不存在,则文档的其余部分会被认为是替代内容,将不会显示出来。
上一篇下一篇

猜你喜欢

热点阅读