分享

191127_01 JS之Canvas绘制教程

 邵发 2019-11-27

JS之Canvas绘制教程

作者:邵发

官网:http:///java

本文是Java学习指南系列教程的官方配套文档。内容介绍在网页前端使用Canvas进行自定义绘制的技术。前端的图表展示、验证码、图片剪裁处理等场合会用到这项技术。

1. 添加<canvas>

<canvas>是一种特殊的网页控件,在它上面可以实现自定义的图形绘制。

例如,

<canvas id='drawing' width='240' height='100' style='background-color: #fdefdf;' ></canvas>

此时定义一个宽度240px、高度100px的画布。显示如下。

需要注意的是,canvas的大小应该用 width/height属性来定义。如果用css定义,后面在绘制文本和图片的时候尺寸会有畸性。

2.  在canvas上绘制

使用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];

3. 填充和描边

在绘制形状和文字时,都有两组函数:一组以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表示透明度。

4. 绘制多边形

三角形、四边形、五边形。。。等等,都称为多边形。例如,绘制一个不规则的四边形。

示例代码如下:

                     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()进行描边。

5. 绘制圆弧和圆形

使用 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 即可。

6. 直线与圆弧的组合

可以由直线和圆弧组合在一起,围成一个特殊的路径。例如,

此图形由左右两个圆弧,和上下两条直线围成。

示例代码如下:

                     //所围区域的参数  , 需要草纸上写比划一下

                     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();

7. 绘制文本

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

8. 图片的绘制

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

                     }

9. 鼠标事件处理

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.offsetXevt.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包在此处可以获取

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约