HTML5 canvas 图形标签的用法快速入门
canvas就是画布,是一个矩形区域,用于在网页上绘制2D图形和图像。canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
canvas坐标体系
电脑上的坐标系和数学上的坐标系稍微有点不同,坐标的原点在绘制区域(这里是Canvas)的左上角,X轴正向朝右,Y轴正向朝下,如下图:
起点为左上角,坐标为 (0,0) 。所有元素的位置都相对于原点来定位。所以图中蓝色方形左上角的坐标为距离左边(X 轴)x 像素,距离上边(Y 轴)y 像素,坐标为 (x,y)。
首先概要说明使用HTML5 canvas绘图的方法步骤
<canvas></canvas>是HTML5中新增的标签,用于绘制图形,实际上,这个标签和其他的标签一样,其特殊之处在于该标签可以获取一个CanvasRenderingContext2D对象,我们可以通过JavaScript脚本来控制该对象进行绘图。
<canvas></canvas>只是一个绘制图形的容器,除了id、class、style等属性外,还有height和width属性。如:
<canvas id="MyCanvas" width="300" height="300">
使用javascript在<canvas>>元素上绘图主要有三步:
获取<canvas>元素对应的DOM对象,这是一个Canvas对象;如:
var canvas = document.getElementById("MyCanvas ");
调用Canvas对象的getContext()方法,得到一个CanvasRenderingContext2D对象;如:
var context = canvas.getContext("2d");
调用CanvasRenderingContext2D对象进行绘图。如画一条直线:
//设置对象起始点和终点
context.moveTo(10,10);
context.lineTo(200,200);
下面给出比较完整的代码
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>canvas绘图演示</title>
<style>
#canvas{
border: 1px solid #ADACB0;
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<canvas id="MyCanvas" width="300" height="300">
你的浏览器还不支持canvas
</canvas>
</body>
<script>
var canvas = document.getElementById("MyCanvas");
var context = canvas.getContext("2d");
//设置对象起始点和终点
context.moveTo(10,10);
context.lineTo(200,200);
//设置样式
context.lineWidth = 2; //线宽
//绘制
context.stroke();
</script>
</html>
保存文件名为:CanvasDemo.html,用浏览器打开,效果如下图(我的保存路径D:\HTML5_canvas示例):
创建 Canvas 元素
向 HTML5 页面添加 canvas 元素。规定元素的 id、宽度和高度:
<canvas id="myCanvas" width="200" height="100"></canvas>
提示:canvas的默认宽高是300*150,单位都是 px。
例1、创建画布(Canvas)代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5Canvas示例1</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<!-- [html注释] 设置画布的可绘制区域:width="300" height="300" 。JavaScript 代码可以访问该区域。-->
<canvas id="tutorial" width="300" height="300"></canvas>
</script>
</body>
</html>
保存文件名为:CanvasDemo1.html,用浏览器打开,效果如下图(我的保存路径D:\HTML5_canvas示例):
绘制长方形
上面的例1中,画布是空白的,那么如何中其中绘制图形呢?
先看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:指的是绘制的矩形的宽和高。
例2、绘制两个长方形
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5Canvas示例2</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<!-- [html注释] 设置画布的可绘制区域:width="300" height="300" 。JavaScript 代码可以访问该区域。-->
<canvas id="tutorial" width="300" height="300"></canvas>
<script>
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();
</body>
</html>
保存文件名为:CanvasDemo2.html,用浏览器打开,效果如下图:
绘制线段
需要用到的方法:
beginPath() 新建一条路径,路径一旦创建成功,图形绘制命令被指向到路径上生成路径
moveTo(x, y) 把画笔移动到指定的坐标(x, y)。相当于设置路径的起始点坐标。
closePath() 闭合路径之后,图形绘制命令又重新指向到上下文中
stroke() 通过线条来绘制图形轮廓
fill() 通过填充路径的内容区域生成实心的图形
例3、绘制三角形
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5Canvas示例3</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<!-- [html注释] 设置画布的可绘制区域:width="300" height="300" 。JavaScript 代码可以访问该区域。-->
<canvas id="tutorial" width="300" height="300"></canvas>
<script>
//JavaScript 代码
function draw(){
var canvas = document.getElementById('tutorial');
if(!canvas.getContext) return;
var ctx = canvas.getContext("2d");
//绘制3角形
ctx.beginPath(); //新建一条path
ctx.moveTo(50, 50); //把画笔移动到指定的坐标
ctx.lineTo(200, 50);
ctx.lineTo(200, 200);
ctx.closePath(); //闭合路径,会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
ctx.stroke(); //绘制路径——描边
}
draw();
</script>
</body>
</html>
保存文件名为:CanvasDemo3.html,用浏览器打开,效果如下图:
绘制圆弧
有两个方法可以绘制圆弧:
1、arc(x, y, r, startAngle, endAngle, anticlockwise): 以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧度结束。anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。
注意:
这里的度数都是弧度。角度转换成弧度:radians=(Math.PI/180)*degrees
0 弧度是指的 x 轴正方向。
2、arcTo(x1, y1, x2, y2, radius): 根据给定的控制点和半径画一段圆弧,最后再以直线连接两个控制点。
例4、绘制圆弧源码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5Canvas示例4</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<!-- [html注释] 设置画布的可绘制区域:width="300" height="300" 。JavaScript 代码可以访问该区域。-->
<canvas id="tutorial" width="300" height="300"></canvas>
<script>
//JavaScript 代码
function draw(){
var canvas = document.getElementById('tutorial');
if(!canvas.getContext) return;
var ctx = canvas.getContext("2d");
//绘制3角形
ctx.beginPath(); //新建一条path
ctx.arc(100,100,80,0*Math.PI/180,270*Math.PI/180); //设置路径
ctx.lineWidth=2; //设置轮廓粗细,ctx.strokeStyle="orange"; 轮廓样式 ctx.fillStyle='azure';设置内部填充样式
//ctx.closePath(); //闭合路径,会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做
ctx.stroke(); //绘制路径——描边
}
draw();
</script>
</body>
</html>
保存文件名为:CanvasDemo4.html,用浏览器打开,效果如下图:
上述还只是能静态的画图,下面介绍如何实现拖动鼠标动态地画图。
实现铅笔功能
canvas不能画点。使用lineTo在一个很细微的粒度下,所以肉眼看起来还算是平滑的曲线。首先设置两个数组clickX, clickY,然后监听鼠标在canvas上面的点击-移动-松开这一系列事件,把该过程中的所经过的所有点的坐标写进刚刚的两个数组里。写完之后再用一个方法取出数组的内容把刚刚的路线画出来。状态量sPainting来标志用户是不是真的在画。使用到了四个:mousedown(鼠标按下)mouseup(鼠标松开)mousemove(鼠标移动)mouseout(鼠标离开).从字面意思就很好理解,分别是鼠标按下、松开、移动、离开时就会触发。
例5、canvas铅笔功能——拖动鼠标动态地画图
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5Canvas示例5</title>
<style type="text/css">
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<!-- [html注释] 设置画布的可绘制区域:width="600" height="400" 。JavaScript 代码可以访问该区域。-->
<canvas id="myCanvas" width="600" height="400"></canvas>
<script>
//JavaScript 代码
var canvas, context,
isPainting,
clickX, clickY, clickDrag;
var mouseDown = function(e){
var mouseX = e.pageX;
var mouseY = e.pageY;
isPainting = true;
addClick(mouseX, mouseY, false);
redraw();
}
var mouseUp = function(e){
isPainting = false;
redraw();
}
var mouseMove = function(e){
if(isPainting){
var mouseX = e.pageX;
var mouseY = e.pageY;
addClick(mouseX, mouseY, true);
redraw();
}
}
var mouseOut = function(e){
isPainting = false;
}
function addClick(mouseX, mouseY, isDragging){
clickX.push(mouseX);
clickY.push(mouseY);
clickDrag.push(isDragging);
}
//重绘
function redraw(){
context.clearRect (0 , 0, canvas.width , canvas.height );
context.strokeStyle = "#000000";
var numOfPts = clickX.length;
for(var i=0; i<numOfPts; i++){
context.beginPath();
if(clickDrag[i]){
context.moveTo(clickX[i-1], clickY[i-1]);
context.lineTo(clickX[i], clickY[i]);
}else{
context.arc(clickX[i], clickY[i], 0.5, 0, 2*Math.PI, true);
}
context.closePath();
context.stroke();
}
}
//初始化
function init(){
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
isPainting = false;
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
//鼠标事件
canvas.onmousedown = mouseDown;
canvas.onmouseup = mouseUp;
canvas.onmousemove = mouseMove;
canvas.onmouseout = mouseOut;
}
window.onload = init();
</script>
</body>
</html>
保存文件名为:CanvasDemo5.html,用浏览器打开,效果如下图:
有了上述基础,再进一步学习就可以少受挫折了。
最后,给出一个可以换一些颜色和笔迹粗细的代码,拖动鼠标动态地画图。
例6、可以换一些颜色和笔迹粗细的代码,拖动鼠标动态地画图的例子,先给出效果图:
代码如下:
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>HTML5Canvas示例6</title>
<script>
var bot;//画布div
var X,Y,X1,Y1;//坐标
var flag=0;
var time;//定时器ID
var color=0;//记住所选颜色
var lineW=2;//画笔粗细
var canvas;//创建画布
var context;//获取上下文
var isMouseDown=false;//记录鼠标是否按下
window.οnlοad=function(){
//创建画布
canvas=document.getElementById("can");
//获取上下文
context=canvas.getContext("2d");
bot=document.getElementById("bottom");
bot.οnmοusedοwn=mouseDownAction;
bot.οnmοusemοve=mouseMoveAction;
document.οnmοuseup=mouseUpAction;
}
/**
*选中画笔颜色
*/
function pen_click(num){
var chk=document.getElementsByTagName("input");
for(var i=0;i<chk.length;i++){
if(i==num){
chk[i].checked=true;
color=i;
}else {
chk[i].checked="";
}
}
}
/**
* 画笔粗细
*/
function line_wid(num){
lineW=num;
}
/**
*鼠标按下
*/
function mouseDownAction(e){
isMouseDown=true;
//记录下鼠标点击的时候的位置
X= e.offsetX;
Y= e.offsetY;
}
/**
*鼠标移动
*/
function mouseMoveAction(e){
if(isMouseDown){
X1= e.offsetX;
Y1= e.offsetY;
drowline(X,Y,X1,Y1);
flag++;
}
}
/**
*鼠标弹起来
*/
function mouseUpAction(e){
isMouseDown=false;
flag=0;
}
/**
* 绘制
*/
function drowline(num1,num2,num3,num4){
//开启新的路径
if(flag)
context.beginPath();
//移动画笔的初始位置
context.moveTo(num1,num2);
context.lineWidth=lineW;
if(color==0){
context.strokeStyle="red";
}else if(color==1){
context.strokeStyle="green";
}else if(color==2){
context.strokeStyle="blue";
}
//移动画笔的结束位置
context.lineTo(num3,num4);
//开始绘制
context.stroke();
if(flag!=0){
X=X1;
Y=Y1;
}
}
function clear_pic(){//清除画布
context.clearRect(0,0,600,400);
}
</script>
</head>
<body>
<div id="left">
<div id="top">
<div class="top_left"><!-- 画笔颜色选择 -->
<img src="img/pen_red.gif" style="border: 2px solid transparent" οnclick="pen_click(0)"><input type="checkbox" style="position: absolute;top: 38px;left: 48px" checked οnclick="pen_click(0)">
<img src="img/pen_green.gif" style="border: 2px solid transparent" οnclick="pen_click(1)"><input type="checkbox" style="position: absolute;top: 38px;left: 95px" οnclick="pen_click(1)">
<img src="img/pen_blue.gif" style="border: 2px solid transparent" οnclick="pen_click(2)"><input type="checkbox" style="position: absolute;top: 38px;left: 142px" οnclick="pen_click(2)">
</div>
<div class="top_right"><!-- 画笔粗细选择 -->
<img src="img/pen_thin.gif" οnclick="line_wid(2)">
<img src="img/pen_medium.gif" οnclick="line_wid(4)">
<img src="img/pen_thick.gif" οnclick="line_wid(8)">
</div>
</div>
<div id="bottom"><!-- 画板 -->
<canvas id="can" width="600" height="400"></canvas>
</div>
</div>
<div class="bottom">
<hr>
<input type="button" value="清除画布" style="position: absolute;top: 460px;left: 66px"οnclick="clear_pic()">
</div>
</body>
<style>
*{
margin: 0px;
padding: 0px;
}
#left{
width: 500px;
height: 450px;
float: left;
}
.top_left{
margin-left: 50px;
float: left;
}
.top_right{
margin-right: 50px;
float: right;
}
#bottom{
width: 600px;
height: 400px;
border: solid 2px coral;
float: left;
}
</style>
</html>
保存文件名为:CanvasDemo6.html,用浏览器打开可以试试效果。
注意,在CanvasDemo6.html文件所在的位置,建立一个img文件夹,包含如下图片