一、概述

canvas它和其它的HTML5标签的使用基本一致,但是它相当于在浏览器中建立一个画布,可以再这个画布上画图、创建动画甚至是3D游戏。由于canvas要适配不同终端的分辨率,所以尽可能的在标签内设置高度和宽度,这个也符合W3C的标准。代码格式如下,当浏览器不支持canvas标签的时候,会显示其中的文字。

<canvas id="main" width="800" height="600" >
亲,您的浏览器不支持canvas
</canvas>

而在canvas的坐标体系中,是以左上角为坐标原点,向右为x轴正方向,向下为y轴正方向,如下图

而在canvas中,进行绘制需要首先获取canvas的上下文环境context,而后调用API进行图像的绘制

var canvas = document.getElementById("main"),
ctx = canvas.getContext("2d");

二、线条的绘制和填充

在canvas中,各个图像绘制代码可以通过beginPath()和closePath()这两个函数进行包裹,主要用于分割各个画图,表示开始和结束。线条的绘制主要调用方法是moveTo(x,y)、lineTo(x,y)、stroke()、arc()、arcTo()、fill(),使用的属性包括lineWidth、lineCap、lineJoin、strokeStyle、fillStyle等。

1、画出边角为圆角的一条线段

ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 6;
ctx.lineCap = "round";
ctx.moveTo(400,400);
ctx.lineTo(600,400);
ctx.stroke();
ctx.closePath();

效果图为:

其中strokeStyle表示线条的颜色,lineWidth表示线条的宽度,lineCap设置线条的边缘为圆角,lineCap的属性有butt|round|square,第一个是默认值表示平直的边缘,round为圆角,square为正方的边缘。moveTo(x,y)表示划线的起点为(x,y)坐标,而lineTo(x,y)设置线条的终点为(x,y),最后通过调用stroke()方法进行绘制。

2、画出两条线段,焦点为圆角

ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 10;
ctx.lineJoin = "round";
ctx.moveTo(400,500);
ctx.lineTo(600,500);
ctx.lineTo(600,600);
ctx.stroke();
ctx.closePath();

效果图为:

和上面的demo的不同点在于使用的属性为lineJoin,同样它也有三个属性bevel|round|miter,第一个是默认值表示斜角,而miter表示尖角。同时lineTo(x,y)可以调用多次,进行线段的绘制,所以可以通过moveTo()和lineTo()这两个方法进行多边形的绘制

3、矩形的绘制并填充颜色

ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(100,50);
ctx.lineTo(100,100);
ctx.lineTo(50,100);
ctx.lineTo(50,50);
ctx.lineWidth = 4;
ctx.strokeStyle = "red";
ctx.stroke();
ctx.fillStyle = "blue";
ctx.fill();
ctx.closePath();

效果图为:

通过moveTo()和lineTo()方法进行多边形的绘制后,得到了一个闭合区间,就可以调用fill()方法对其中的颜色进行填充,fillStyle则是设置闭合区间内的颜色。如果不用stroke()方法,也就是不绘制外边框的线条,则可以省去最后的那个回到起点的方法ctx.lineTo(50,50),因为fill()会自动将起点和终点进行连接得到一个闭合区间。

如果是单纯的矩形而非不规则的多变型的时候,可以直接调用canvas的api方法strokeRect(x,y,w,h)和fillRect(x,y,w,h);前两个参数表示起点的坐标,后两个表示矩形的宽度和高度。

ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = "darkgray";
ctx.strokeRect(50,50,200,100);
ctx.closePath(); ctx.beginPath();
ctx.fillStyle = "coral";
ctx.fillRect(300,50,200,100);
ctx.closePath();

效果图为:

4、弧形的绘制

首先是arc(x,y,r,beginPi,endPi,anticlockwise)函数,前两个参数表示圆心的x,y坐标,中间的那个r表示圆的半径,后两个参数表示起始弧度和结束弧度,最后表示是否是逆时针绘制,默认是false即顺时针绘制。在canvas中,无论是顺时针还是逆时针,圆的弧度都是一个定值,如下图:

ctx.beginPath();
ctx.arc(320,200,50,0,Math.PI*2);
ctx.lineWidth = 3;
ctx.strokeStyle = "black";
ctx.stroke();
ctx.fillStyle = "chartreuse";
ctx.fill();
ctx.closePath();

效果图为:

还可以通过arcTo(x1,y1,x2,y2,r);绘制圆弧,它与moveTo(x,y)一起进行使用,(x,y)(x1,y1)与(x1,y1)(x2,y2)以这两条线段为切线,绘制半径为r的圆弧,起点和终点为那两个切点。

ctx.beginPath();
ctx.lineTo(400,200);
ctx.arcTo(500,200,500,300,100);
ctx.strokeStyle = "aqua";
ctx.stroke();
ctx.closePath();

效果图为:

最后就是贝塞尔曲线绘制曲线,由于数学算法比较复杂,也没有过多研究

a、二次贝塞尔曲线

cxt.quadraticCurveTo(x1,y1,x2,y2);

同样是与 cxt.moveTo(x0,y0);混用,其是通过(x1,y1)为控制点画圆弧

http://blogs.sitepointstatic.com/examples/tech/canvas-curves/quadratic-curve.html

该网址是二次贝塞尔曲线的测试网址

b、三次贝塞尔曲线

cxt.bezierCurveTo(x1,y1,x2,y2,x3,y3);

同样是与 cxt.moveTo(x0,y0);混用,其是通过(x1,y1),(x2,y2)为控制点画圆弧

http://blogs.sitepointstatic.com/examples/tech/canvas-curves/bezier-curve.html

该网址是三次贝塞尔曲线的测试网址

(ps:其中三次曲线比二次曲线好用,他可以绘制会各种突出弧形以及波浪)

三、图形变换

无论哪种语言处理图像时,都有一个思想。那就是先确定好图形画法函数,然后通过图形变换函数将图形进行位移、旋转角度、大小的改变。

在canvas中,由于canvas是一种基于状态的编程,所以之前提到在绘制点与点之间的直线以及颜色时使用

context.beginPath();

context.closePath();

这两个函数可以将点与点之间的函数的状态进行隔离,并且还可以完成封闭的图形,即首尾点会自动连接

而在图形变换中也需要这样的规范写法,它们分别是

context.save();

context.restore();

通过这两个函数将函数变换的函数隔离开

1、translat

context.translat(x,y)

它是将图像进行平移,x是水平方向平移的距离,y是垂直方向平移的距离

ctx.save();
ctx.translate(50,50);
ctx.beginPath();
ctx.strokeRect(10,10,20,20);
ctx.closePath(); 
ctx.restore();

效果图为:

本来这个矩形应该绘制在左上角,经过图形变换把其向x,y两个方向各偏移了50像素(PS:需要注意的是图形变换的函数调用,要在绘制函数之前执行)

2、rotate

context.rotate(rot);

该方法是用来设置图片的旋转角度,其中rot应该是弧度,若传入的是角度的话需要转换,如80,需要些为Math.PI*80/180

ctx.save();
ctx.rotate(20*Math.PI/180);
ctx.beginPath();
ctx.fillRect(100,100,50,50);
ctx.closePath();
ctx.restore();

效果图为:  向顺时针方向偏移了20度

3、scale

context.scale(x,y)

该方法是用来进行图像缩放的,其中x为水平方向缩放的比例,y是垂直方向缩放的比例

(PS: 该函数存在一个问题,就是在缩放时,图像的左上角的位移也会发生同样比例的改变并且图像的边框线也会发生同样的改变)

ctx.save();
ctx.scale(0.5,0.5);
ctx.beginPath();
ctx.fillRect(100,100,200,200);
ctx.closePath();
ctx.restore();

就是将正方形的x和y方向均缩放到一半的大小

4、transform

context.transform(a,b,c,d,e,f);

首先该方法是上述方法的总和,因为该方法是通过单位矩阵的方式对图像进行改变,图像在本质上就是许多由0,1的矩阵组合而成,如下表格

a c e
b d f
0 0 1

a代表水平缩放,默认为1;b代表水平倾斜,默认为0;c代表垂直倾斜,默认为0;

d代表垂直缩放,默认为1;e代表水平位移,默认为0;f代表垂直位移,默认为0;

所以用transfrom函数可以实现,上面3种图像变换。

四、其它杂七杂八

1、文字显示

ctx.fillText(string,x,y,[maxlen]);

ctx.strokeText(string,x,y,[maxlen]);

其中第一个函数是需要写出的文本值,其中x,y是文本的坐标。而maxlen是可选参数,设置其文字的最大长度。

其文字可以设置相关参数

ctx.font的默认值是"20px sans-serif"

其参数包括context.font = font-style font-variant font-weight

font-size font-family其中各个参数有个字的值

context.textAlign = left center right该属性是设置文字的居中、居左、居右

context.textBaseline = top middle bottom该属性是设置文字的垂直居上、居中、居下。

ctx.beginPath();
var str = "古月枫"
ctx.strokeStyle = "red";
ctx.fillStyle = "aqua";
ctx.font = "40px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.strokeText(str,100,100,200);
ctx.fillText(str,100,150,200);
ctx.closePath();

效果图为:

2、阴影

在canvas中并没有一个针对阴影的函数,它是通过状态进行添加,无论是线条、矩形、圆或者是文字都可以通过以下函数添加阴影效果

ctx.shadowColor = "gray";    //设置阴影背景的颜色

ctx.shadowOffsetX = 10;    //设置阴影x轴方向的突出像素,该值可以为负数

ctx.shadowOffsetY = 10;    //意思同上,只不过这个是针对Y轴的

ctx.shadowBlur = 5;    //设置阴影的模糊程度,0为无模糊,值越大模糊越重

ctx.beginPath();
var str = "古月枫"
ctx.fillStyle = "aqua";
ctx.font = "40px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.shadowColor = "gray";
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.shadowBlur = 3;
ctx.fillText(str,100,150,200);
ctx.closePath();

效果图为:

3、全局变量,透明度

ctx.globalAlpha设置全局的透明度,它的默认值为1,而将其改变为0到1的值时,画布上的图形就有了透明效果。由其作用范围为全局,所以要用save()和restore()方法进行包裹使用

4、剪辑 ctx.clip();

这个功能只有上面所说的一个函数,它是与lineTo、fillRect、arc等可绘制闭合空间的函数混用,其用处是为了canvas只能在一个封闭的空间内进行绘制,超出这个空间的图形绘制不显示,比较常用的运用方式是制作探照灯的效果。

ctx.save();
ctx.beginPath();
ctx.arc(200,200,100,0,Math.PI*2);
ctx.clip();
ctx.fillStyle = "chartreuse";
ctx.fillRect(100,100,200,200);
ctx.closePath();
ctx.restore();

效果图为:

先定义了一个圆形的剪辑区域,然后画了一个大范围的正方形,但是只能显示这个圆形范围的图像

5、交互

由于在canvas中整个canvas是作为一个画布,而且其中画出的各种图形都无法将其作为一个对象通过事件绑定的形式进行交互,所以在canvas中的事件绑定是直接绑定在canvas上,然后通过对用户在canvas画布上操作的坐标的判断进行交互。

其中最基本的方法如下

a、对canvas标签进行事件绑定,JS以及jQuery都成

b、获取在画布上用户操作的坐标

var x = event.clientX - canvas.getBoundingClientRect().left;

var y = event.clientY - canvas.getBoundingClientRect().top;

它是通过计算用户在整个页面的操作坐标与canvas在页面的左上边距进行计算的

canvas基础学习(一)的更多相关文章

  1. canvas基础学习

    /** * Created by ty on 2016/7/11. * canvas 基础 */ window.onload = function() { var canvas = document. ...

  2. HTML5 <canvas> 基础学习

    HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成. <canvas> 标签只是图形容器,您必须使用脚本来绘制图形 创建一个画布( ...

  3. canvas一周一练 -- canvas基础学习

    从上个星期开始,耳朵就一直在生病,里面长了个疙瘩,肿的一碰就疼,不能吃饭不能嗨 (┳_┳)……在此提醒各位小伙伴,最近天气炎热,一定要注意防暑上火,病来如山倒呀~ 接下来我正在喝着5块一颗的药学习ca ...

  4. canvas基础学习(四)

    今天逛天猫时,看见优衣库店铺首页有个这个飘雪效果,顿时觉得好酷炫,立马从里面copy代码进行学习. 之前我也做过一些canvas特效,往往在canvas全屏时,canvas下层的div就无法进行dom ...

  5. canvas基础学习(二)

    一.图像绘制 canvas绘制图像的方法是ctx.drawImage();该方法有三种使用方式 1.ctx.drawImage(img,x,y); img是指图像对象,x和y分别是这个图像左上角在ca ...

  6. Canvas基础学习(一)——实现简单时钟显示

    HTML5最受欢迎的功能就是<canvas>元素.这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态地在这个区域中绘制图形.关于<canvas>元素的一些 ...

  7. canvas基础学习笔记

    canvas基本用法 1.什么是canvas(画布)  <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形,例如,它可以用于绘制图形,创建动 ...

  8. canvas基础学习(三)

    一.图片加载控件 在canvas效果制作中常常要使用多张图片,为了提高用户体验,需要给用户提供一个图片加载中的过度页面效果.过度效果,我在项目中使用的是Sonic.js,它在git上的地址为https ...

  9. HTML5移动开发学习笔记之Canvas基础

    1.第一个Canvas程序 看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子. 效果图为: 代码如下: <!DOCTYPE html> < ...

随机推荐

  1. 20170413 F110学习

                  F110 学习: Tcode: F110  自动付款业务, FBZP   维护收付程序设置 FBL1N   供应商行项目 XK03   显示供应商(银行信息维护) F110 ...

  2. zabbix-2.4.8-1添加tcp状态监控

    1.安装zabbix-agentyum -y install zabbix-2.4.8-1.el6.x86_64.rpm zabbix-agent-2.4.8-1.el6.x86_64.rpm2.编辑 ...

  3. 算法题 18 像素翻转 牛客网 CC150

    算法题 18 像素翻转 牛客网 CC150_P114 题目描述 有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时 ...

  4. CRC冗余校验码的介绍和实现

    from:http://yoyo.play175.com/p/200.html 节选至百度百科: 首先,任何一个由二进制数位串组成的代码,都可以惟一地与一个只含有0和1两个系数的多项式建立一一对应的关 ...

  5. 建议44:理解模块pickle优劣

    # -*- coding:utf-8 -*- ''' pickle 估计是最通用的序列化模块了,它还有个C 语言的实现cPickle,相比pickle 来说 具有较好的性能,其速度大概是pickle ...

  6. argparse.add_argument()应用

    ArgumentParser.add_argument(name or flags…[, action][, nargs][, const][, default][, type][, choices] ...

  7. Flume+Kafka+storm的连接整合

    Flume-ng Flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统. Flume的文档可以看http://flume.apache.org/FlumeUserGuide.html ...

  8. FreeMarker 使用实例

    以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成: 1,文本:直接输出的部分 2,注释:<#-- ... - ...

  9. Nginad Server安装

    前言 Nginad是一个基于php的开源项目,它既可以作为静态配置的Ad Server,也可以作为动态的RTB Exchange使用.代码结构比较直接明了,挺适合用作学习的.本文如果有理解错误的地方, ...

  10. linux基础(10)-导航菜单

    导航菜单实战 例:编写一个shell脚本,包含多个菜单,其中需要一个退出选项:可单选也可多选:根据序号选择后,显示所选菜单名称. #!/bin/bash ####################### ...