HTML5 Canvas

Canvas HTML 5中引入它,可以做很多事情:画图、动画、游戏开发等等。本篇就主要讲解一下Canvas的基本作图。

 内容摘要

  •  1、Canvas 基础知识
    • 1.1 Canvas元素
    • 1.2 CanvasRenderingContext2D简介
  •  2、Canvas 基本作图
    • 2.1 线条
      • 2.1.1 直线 (Line)
      • 2.1.2 曲线 (curves)
      • 2.1.3 Path
      • 2.1.4 矩形 (rectangle)
      • 2.1.5 线条样式
    • 2.2 文本
      • 2.2.1 文本样式
      • 2.2.2 填充文本
    • 2.3 图像视频
    • 2.4 填充样式
  •  3、Canvas 坐标变换
    • 3.1 translate 平移
    • 3.2 scale 缩放
    • 3.3 rotate 旋转
    • 3.4 transform 变换

1Canvas
基础知识

1.1 Canvas 元素

Canvas 中文翻译为:画布。

 

<canvas id=”yourCanvasId” width=”300” height=”150” />

Canvas元素除了公用属性外,只有两个额外的属性:width, height,他们都是没有单位的,其实单位是px,但是不能写单位。如果不指定这两个属性,默认是width300height150

众所周知,html元素的样式,都可以用css样式来指定。Canvas也不例外。

<html>

<head>

<title>Canvas – 01</title>

<style>

body{

background:#dddddd;

}

 

#canvas{

margin:20px;

padding:20px;

background:#ffffff;

border:thin inset #aaaaaa;

width:600px;

height:300px;

}

</style>

</head>

<body>

<canvas >

Canvas not supported

</canvas>

<script type=”text/javascript”>

var canvas = document.getElementById(“canvas”),

ctx = canvas.getContext(“2d”);

 

ctx.font=\’38pt Arial\’;

ctx.fillStyle=\’cornflowerblue\’;

ctx.strokeStyle=\’blue\’;

ctx.fillText(“Hello Canvas”, canvas.width/2 -150, canvas.height/2 + 15);

ctx.strokeText(“Hello Canvas stroke”, canvas.width/2 -200, canvas.height/2 + 80);

</script>

</body>

</html>

 

我们期望的结果是这样的:

 

 

 

而实际的执行结果:

 

 

从执行结果看,它确实一个放大的hello,这是为什么呢?

 

其实我认为可以这样理解它,它是一个放映布,因为真正的绘图不在它上的,而是在一个绘图板上,绘图完毕投影到放映布上。这一点,类似于我们中学时候用过的幻灯片放映机,在一张玻璃板(绘图板)上写上习题,然后投影到放映布或者白墙上(画布)。

 

所以呢,这样一想,就明白了,当css样式中的width,height属性值与canvas元素的width,height的属性值不同时,会自动的将绘图板上的内容进行缩放到画布上。

 

 

Canvas 元素目前有三个方法:

 

 

 

 

通过getContext(“2d”);能够取得CanvasRenderingContext2D对象,然后就可以基于此上下文对象来作2d图了

 

通过getContext(“3d”);就可以进行3d作图,3d作图底层用的是WebGL

 

1.2 CanvasRenderingContext2D简介

 

2、基本作图

 

2.1、线条

使用Canvas作图时,默认情况下是有这样一个坐标轴的:

 

 

 

 

在使用canvas作图时,需要按照一定的顺序来编写代码。

1)直线(Line

要画一条线,代码编写过程一般是这样的:

Ctx.beginPath(); // 声明要开始一条线

Ctx.moveTo(x,y);// 指定线的起点。moveTo,就像是将画笔移动到某个点。

Ctx.lineTo(x,y);// 指定线的终点

Ctx.lineCap=”round”;// 设置线的两端(线帽),可选值有:butt,round,square

Ctx.lineWidth=15;// 指定线的宽度

Ctx.strokeStyle=”#ff0000”;// 设置线的颜色,不设置则根据当前颜色。默认是黑色。

Ctx.stroke(); // 开始描边

 

2)曲线(Curves

使用canvas可以做的曲线主要包括:圆弧、bezier曲线、quadratic曲线。

 

2.1) 圆弧(arc

 

要做一条圆弧,编码的顺序一般是这样的:

Ctx.beginPath(); // 声明要开始一条新的path

Ctx.arc(x,y,radius,startAngle,endAngle,antiClockwise); //指定弧线path

Ctx.lineWidth=15;// 指定线的宽度

Ctx.strokeStyle=’black’; // 指定线的颜色

Ctx.lineCap=”square”;// 指定线帽

Ctx.stroke();// 开始描边

 

在做圆弧时,最主要的就是ctx.arc

 

该方法的参数列表:

参数

描述

x

圆的中心的 x 坐标。

y

圆的中心的 y 坐标。

r

圆的半径。

startAngle

起点的弧值。(弧的圆形的三点钟位置是 0 度)。

endAngle

终点的弧值。

antiClockwise

是否逆时针绘图,可选。False = 顺时针,true = 逆时针。

 

 

 

 

这里用的是弧度,不是角度。可能大家对角度都比较熟悉。

 

从起点,按照顺时针(或者逆时针)方向转一周,是360度(角度)。

如果以弧度来表示,则是按照顺时针(或者逆时针)方向转一周,弧度是 2*PI

 

既然这里要求的是弧度值,大家熟悉的是角度,那么怎么将角度转换为弧度呢?

假定 f(x) => 360x = 2*PI
可以很容易推导出
x=PI/180。也就是1度(角度)=PI/180弧度。

那么90o  = 90 * PI /180= 0.5 PI; 180o
= PI; 360o = 2*PI

 

 

下图是一张按照顺时针转动的弧度:

 

 

 

2.2)二次方曲线(quadratic curves

二次方曲线,也称为抛物线。

维基百科时有关二次方曲线的描述:

https://en.wikipedia.org/wiki/Quadratic_function

 

 

Ctx.beginPath(); // 开始画线

Ctx.moveTo(x,y)//
起点

Ctx.quadraticCurveTo(cx,cy,ex,ey);// 指定要画抛物线

Ctx.lineWidth=12; // 指定线宽带

Ctx.strokeStyle=”black”;// 指定线颜色

Ctx.lineCap=’butt’; // 指定线帽

Ctx.stroke(); // 开始描边

 

 

其中quadraticCurveTocx,cy,ex,ey)前两个参数表示控制点坐标,后两个参数表示终点坐标。

 

 

 

下面是一个demo:

 

 

 

 

 

2.3)三次方曲线(Bezier Curve

 

Quadratic curve 有一个控制点,而Bezier curve
有两个控制点。

指定画bezier曲线的方法是:

Ctx.bezierCurveTo(c1x,c1y, c2x, c2y, ex, ey)

 

 

 

 

 

3) Path

在画line,curve时,我们都用beginPath()来表示要启动一条path,然后进行画直线或者曲线。其实可以将他们串连起来。

 

 

 

 

 

 

 

 

 

在多条线串联的地方,称为lineJoin,它有三种形式:

 

 

 

4) 矩形(rectangle

4.1 绘制矩形

绘制矩形,有两种方式:

Ctx.rect(x,y, width, height);

Ctx.strokeRect(x,y,width, height)

区别是第一种需要beginPath(),第二种不需要。

 

 

 

 

 

 

 

 

4.2 填充矩形

 

绘制并填充矩形。

Ctx.fillRect(x,y,width, height);

 

4.3 清理rect

 

会把指定矩形内的内容全部清空。

 

Ctx.clearRect(x,y,widht, height);

 

 

5) 线条样式

 

 

 

 

 从图上很容易看出来,butt,round,square的区别来。

 

 

 

2.2、文本

2.1 文本样式

css中,设置问题的属性有:

 

 

 

然而并不能通过css style设定canvas中文本的样式。

Canvas中的text有自己的一套设置格式:

 

Ctx.font=”${font-style} ${font-size} ${font-family}” //
指定文本样子,大小,字体

Ctx.fillStyle=”blue” ;// 指定文本颜色

Ctx.textAlign=”center”; // 指定水平方向上的对齐方式

Ctx.textBaseline=”middle” 指定竖直方向上的对齐方式

Ctx.strokeStyle=”blue”; // 指定文本stroke颜色

 

2.2 填充文本

 

Ctx.fillText(text, x, y);

canvas中填充的文本,是不会自动折行的,所以如果文本太长的话,需要自己控制折行显示。

 

 

 

2.3、图像、视频

 

canvas加入图像、画布、视频,,使用drawImage即可。在将图像、画布、视频放到canvas时,可以整体放入,也可以剪切后放入。在使用API时,也有三种用法:

假设要添加的图像、画布、视频为源:

1drawImage(img,x,y);

将源放到canvasx,y处。

2)drawImage(img,x,y,width,height);

将源放到x,y处,并将源以width,height的尺寸来缩放显示。

3drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

将源从sx,sy出开始截取swidth,sheight的内容,然后缩放到width,height的尺寸,放到canvasx,y处。

Image:要使用的图片、画布、视频

Sx,sy:从源的sx,sy坐标处剪切

Swidth,Sheight:源的宽,

X,y:放到canvasx位置

 

 

2.4、填充样式

 

在填充时,可以有三种填充方式:

·color 填充为某种颜色

·gradient 填充为渐变颜色

·按pattern进行填充(使用它可以填充图片)

 

http://www.w3school.com.cn/tags/canvas_fillstyle.asp

 

3、坐标平移、转换、旋转

默认情况下,坐标原点是在Canvas左上角。有时我们需要移动坐标轴、或者xy轴转换来进行操作。

 

3.1 translate 平移坐标轴

该方法是对坐标轴平移

 

 

在执行完 translate后,坐标轴原点位置由原来的 (0,0)变为原来的(70,70)。之后的作图,就以新的坐标原点为(0,0)

那么想要再将坐标原点重置,则需要将坐标轴再进行平移。

 

 

Translate(tx,ty),实际在作图(点,线,面)时,会对grid内每一个要做图点,基于(tx,ty)进行平移运算。这个其实是向量运算。也可以看作是矩阵加运算。

 (x,y) 经过 (tx, ty)
平移后的点的计算,使用矩阵运算就是:

[ x ]         + [tx]   => [x+tx]

[ y ]            [ty]       [y+ty]

 

 

 

 

3.2 scale 缩放

scale(xPercent, yPercent) 参数是x,y轴的缩放百分比。 大于1是放大,小于1是缩小。

 

假设默认是 1个长度占用1个像素。假设画一条长度为 10的直线,就是占用10个像素。

使用scale放大到200%后,画一条长度为 10的直线,就是占用20个像素。

 

也就是缩放的是坐标轴的长度

 

 

[x,y] s [sx, sy] => [sx*x + sy * y]

 

 

 

3.3 rotate 旋转

该方法是对坐标轴旋转

rotateangle)参数是弧度。之前已经说过了,1度(角度)=PI/180弧度,那么假设你想转90o,那么应该是rotate90
* Math.PI/180
)。

 

 

 

3.3 transform 变换

transform(xs,xr,yr,ys,xt,yt) 该方法是对坐标系进行平移、缩放、旋转的综合的操作。

 

xs:x轴缩放

xr:x轴旋转

yr:y轴旋转

ys:y轴缩放

xt:y轴平移

yt:y轴平移

 

 

 

 

 

 

 

 

 

版权声明:本文为匿名原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: