作者:邵发
官网:http://afanihao.cn/java
本文是Java学习指南系列教程的官方配套文档。内容介绍在网页前端使用Canvas进行自定义绘制的技术。前端的图表展示、验证码、图片剪裁处理等场合会用到这项技术。
例如,
此时定义一个宽度240px、高度100px的画布。显示如下。
需要注意的是,canvas的大小应该用 width/height属性来定义。如果用css定义,后面在绘制文本和图片的时候尺寸会有畸性。
使用JavaScript可以在canvas对象上绘制。下面,在canvas上绘制一个80x40的矩形。
对应的代码:
my.test02 = function(){
var canvas = document.getElementById('drawing');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
ctx.fillStyle = '#F00';
ctx.fillRect(10,10, 80,40);
}
首先,使用getElementById()得到canvas对象,然后得到GraphicsContext,然后使用ctx进行绘制就行了。如果你之前学过Java学习指南的Swing高级篇,则此绘制技术对你十分容易,因为绘制的所有的概念都是相同的。
也可以使用jQuery来获取canvas对象,例如:
var canvas = $('#drawing')[0];
在绘制形状和文字时,都有两组函数:一组以fill***打头,称为填充。一组以stroke***打头,称为描边。
下面,绘制两个矩形,如图所示。
第一个矩形,以红色填充内容。第二个矩形,以蓝色描绘边框。
对应代码如下。
my.test03 = function(){
var canvas = document.getElementById('drawing');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
// 填充
ctx.fillStyle = '#F00'; // 填充色
ctx.fillRect(10,10, 80,40);// 参数为 x, y, width, height
// 描边
ctx.strokeStyle = '#3f778e';
ctx.strokeRect(100,10, 80,40);
}
其中,fillRect()用于填充一个矩形区域,而storeRect()用于描边。而fillStyle指定填充色,strokeStyle指定边框颜色。
也可以指定一个半透明的颜色,例如 ctx.fillStyle = 'rgba(240,240, 240, 0.5) ' 最后一个0.5表示透明度。
三角形、四边形、五边形。。。等等,都称为多边形。例如,绘制一个不规则的四边形。
示例代码如下:
ctx.beginPath(); // 开始一个路径
ctx.moveTo(10,10); // 指定起点
ctx.lineTo(10, 60); // 以直线连接到下一个顶点
ctx.lineTo(40, 80); // 以直线连接到下一个顶点
ctx.lineTo(70, 10); // 以直线连接到下一个顶点
ctx.closePath(); // 闭合路径, 回到起点
ctx.fill(); // 绘制路径所围的闭合区域
这里的Path表示一个路径,一个闭合的路径正好围成一个区域。从beginPath()开始,到closePath()结束,完成一个路径的定义。最后用ctx.fill()对所围在的区域进行填充,或ctx.stroke()进行描边。
使用 arc() 可以用来定义一个圆弧路径。
arc(x, y, radius, startAngle, endAngle, anticlockwise)
其中,x,y是圆心坐标,radius为半径,startAngle为起点弧度,endAngle为终点弧度,anticlockwise表示反时针方向(true)或逆时针(false)。
例如,
从右上角的45度(PI/4) 位置,到上方的270度( PI*3/2)位置,以逆时针连接。
示例代码如下:
ctx.beginPath();
ctx.arc(50, 50, 30, Math.PI/4, Math.PI*3/2, true);
ctx.closePath();
ctx.stroke();
如果要绘制一个完整的圆形,可以指定起点为0,终点为PI * 2 即可。
可以由直线和圆弧组合在一起,围成一个特殊的路径。例如,
此图形由左右两个圆弧,和上下两条直线围成。
示例代码如下:
// 所围区域的参数, 需要草纸上写比划一下
var cx = 10, cy = 10; // 左上角
var cw = 60, ch = 40; // 宽高
var cr = 20; // 圆弧半径
// 定义一个由圆弧和直线围成的路径
ctx.beginPath();
ctx.arc(cx+cr, cy+cr, cr, Math.PI*3/2, Math.PI/2, true);
ctx.lineTo(cx + cw - cr, cy + ch);
ctx.arc(cx + cw - cr, cy + cr, cr, Math.PI/2, Math.PI*3/2, true);
ctx.closePath();
//描绘路径
ctx.strokeStyle = '#F00'; // 填充色
ctx.stroke();
使用fillText() 或 strokeText() 可以来绘制文字。例如。
示例代码如下,
ctx.fillStyle = '#F00';
ctx.font = '30px 宋体';
ctx.textAlign = 'left' ; // 水平位置
ctx.textBaseline = 'top'; // 竖直位置
ctx.fillText("阿发你好", 20, 20);
其中,font用于指定字体,textAlign指定水平对齐,textBaseline用于指定竖直对齐。
fillText ( text, x, y) 带三个参数,x, y用于指定绘制的位置。x, y的位置和 textAlign, textBaseline一起,决定文本绘制的位置。
例如,'left' 表示x为文本最左侧位置,'top'表示y指定文本的最上沿位置。
textAlign的选项: left, right , center
textBaseline的选项:top, middle, bottom
在Canvas上也可以绘制图片,例如。
事先得在网站里准备好一张图片,例如,img/bg.jpg ,然后在JS里加载它。
var img = new Image();
img.src = './img/bg.jpg';
img.onload = function(){
}
其中,img.src指定图片的路径URL。当图片加载完成时,img.onload()回调被执行。在onload()里把图片绘制出来即可。
示例代码如下:
img.onload = function(){
// 图片的下载需要一定时间,所以等其onload之后,再绘制到canvas上
ctx.drawImage(img, 0,0, w, h);
// 在图片上再绘制一些文本
ctx.fillStyle = '#F00';
ctx.font = '20px 宋体';
ctx.textAlign = 'center' ;
ctx.textBaseline = 'top';
ctx.fillText("阿 发 你 好", w/2, 20);
}
canvas和所有DOM对象一样,支持鼠标事件处理,如mousedown, mouseup, mousemove等。例如,在图片上支持用鼠标划选一个短形区域,效果如下所示。
当鼠标按下时,应记录鼠标开始划选的位置startX, startY,例如:
canvas.addEventListener('mousedown', function(evt){
my.pressed = true;
my.startX = evt.offsetX;
my.startY = evt.offsetY;
my.endX = evt.offsetX;
my.endY = evt.offsetY;
my.repaint();
});
其中,evt.offsetX和evt.offsetY表示鼠标的位置。
当鼠标拖动划选时,根据鼠标的当前位置来绘制一个矩形。示例代码如下。
canvas.addEventListener('mousemove', function(evt){
if(my.pressed){
my.endX = evt.offsetX;
my.endY = evt.offsetY;
my.repaint();
}
});
其中,endX 和 endY 用于记录鼠标落点的位置。所以,由(startX, startY) 和终点 (endX, endY)便可以绘制出用户选择的短形区域。
Canvas的主要绘制方法就是这些,还是一些高级的变形、坐标变换、旋转功能,和Java Swing里的技术基本一致。以上演示所用的项目源码和JAR包在此处可以获取。