canvas基础学习(一)
一、概述
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基础学习(一)的更多相关文章
- canvas基础学习
/** * Created by ty on 2016/7/11. * canvas 基础 */ window.onload = function() { var canvas = document. ...
- HTML5 <canvas> 基础学习
HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成. <canvas> 标签只是图形容器,您必须使用脚本来绘制图形 创建一个画布( ...
- canvas一周一练 -- canvas基础学习
从上个星期开始,耳朵就一直在生病,里面长了个疙瘩,肿的一碰就疼,不能吃饭不能嗨 (┳_┳)……在此提醒各位小伙伴,最近天气炎热,一定要注意防暑上火,病来如山倒呀~ 接下来我正在喝着5块一颗的药学习ca ...
- canvas基础学习(四)
今天逛天猫时,看见优衣库店铺首页有个这个飘雪效果,顿时觉得好酷炫,立马从里面copy代码进行学习. 之前我也做过一些canvas特效,往往在canvas全屏时,canvas下层的div就无法进行dom ...
- canvas基础学习(二)
一.图像绘制 canvas绘制图像的方法是ctx.drawImage();该方法有三种使用方式 1.ctx.drawImage(img,x,y); img是指图像对象,x和y分别是这个图像左上角在ca ...
- Canvas基础学习(一)——实现简单时钟显示
HTML5最受欢迎的功能就是<canvas>元素.这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态地在这个区域中绘制图形.关于<canvas>元素的一些 ...
- canvas基础学习笔记
canvas基本用法 1.什么是canvas(画布) <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形,例如,它可以用于绘制图形,创建动 ...
- canvas基础学习(三)
一.图片加载控件 在canvas效果制作中常常要使用多张图片,为了提高用户体验,需要给用户提供一个图片加载中的过度页面效果.过度效果,我在项目中使用的是Sonic.js,它在git上的地址为https ...
- HTML5移动开发学习笔记之Canvas基础
1.第一个Canvas程序 看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子. 效果图为: 代码如下: <!DOCTYPE html> < ...
随机推荐
- numpy的random模块详细解析
随机抽样 (numpy.random) 简单的随机数据 rand(d0, d1, ..., dn) 随机值 >>> np.random.rand(3,2) array([[ 0.14 ...
- tcpdump Demo
tcpdump Demo lxw ~$ tcpdump -i eth0 tcpdump: eth0: You don't have permission to capture on that devi ...
- 0607am抽象类&接口&析构方法&tostring&小知识点
/*class ren{ public static $color;//静态 static function () { ren::$color; self::$color;//self只能写在类里面, ...
- 谷歌机器学习速成课程---3降低损失 (Reducing Loss):梯度下降法
迭代方法图(图 1)包含一个标题为“计算参数更新”的华而不实的绿框.现在,我们将用更实质的方法代替这种华而不实的算法. 假设我们有时间和计算资源来计算 w1 的所有可能值的损失.对于我们一直在研究的回 ...
- iOS 9 的新功能 universal links
什么是 universal links: (通用链接) 一种能够方便的通过传统 HTTP 链接来启动 APP, 使用相同的网址打开web page和 APP的方式. 第一点,链接打开网址 顾名思义 第 ...
- Java底层代码实现多文件读取和写入
需求: "E:/data/"目录下有四个文件夹,如下: 每个文件夹下有几个.csv文件,如下: 将每个文件夹下的.csv文件合并成一个以该文件夹命名的.csv文件. 做法: 找到& ...
- 每天一个Linux命令(43)at命令
at命令用于在指定时间执行命令.at允许使用一套相当复杂的指定时间的方法.可以用相对时间法指定,也可以用绝对时间法指定. (1)用法: 用法: at [选项参数] [时间 ...
- 常用的机器学习&数据挖掘知识点
Basis(基础):MSE(Mean Square Error 均方误差),LMS(LeastMean Square 最小均方),LSM(Least Square Methods 最小二乘法),MLE ...
- request模块 一基础部分
一.HTTP请求 通过requests发送网络请求,方法有get post put delete head options import requests r=requests.get(" ...
- java基础(3)-多线程(1)
java多线程 进程与线程 进程:指一个正在执行的应用程序.每个进程执行都有一个执行顺序,该顺序称为一个执行路径或一个控制单元(进程是资源分配的最小单位).一个进程包含1~n个线程 线程:指进程中某个 ...