本帖最后由 月下枝桠 于 2018-7-18 18:36 编辑
Canvas概念
为什么要学习canvas
什么是Canvas
canvas入门
canvas初体验准备画布 使用js进行绘画 - 拿到canvas画布
- 获取渲染上下文对象(该对象提供了一系列的API集合)
- 使用API绘制需要的图形
[HTML] 纯文本查看 复制代码 <!-- 准备画布:canvas本身不具备画图功能,仅仅是用来展示内容的 -->
<canvas id="cvs"></canvas>
<script>
//通过js提供的api,可以在canvas画布上进
[img]static/image/hrline/line1.png[/img]
//1. 获取到画布
var cvs = document.getElementById("cvs");
//2. 获取到渲染上下文,在画布上可以画2d的和3d的图形
// 说明我要在画布上画2d的图形, 返回的对象中提供了很多画2d图形的api
var ctx = cvs.getContext("2d");
//3. 使用2d上下文进行会话。
//3.1 移动画笔的位置,到100,100的坐标点
ctx.moveTo(100, 100);
//3.2 连线
ctx.lineTo(200, 100);
//3.3 渲染(描边或者填充)
// 注意:moveTo和lineTo仅仅是绘制了一个路径(打草稿),还需要把这条线给渲染出来
ctx.stroke();
</script>
canvas中的坐标系
原点:画布的左上角(0,0),所有元素都是相对与原点定位。 canvas API学习
getContext方法 功能:getContext方法用于获取canvas的上下文对象 语法:HTMLCanvasElement.getContext(contextType); 参数:contextType是一个字符串 使用demo: [JavaScript] 纯文本查看 复制代码 //1. 获取到画布
var cvs = document.getElementById("cvs");
//2. 获取到2d上下文对象
var ctx = cvs.getContext("2d");
console.log(ctx);//CanvasRenderingContext2D对象,进行2d图形的绘制
moveTo方法 功能:设置上下文绘制路径的起点。相当于移动画笔到某个位置 语法:ctx.moveTo(x, y); 参数:x=横坐标 y=纵坐标 注意:绘制线段前必须先设置起点,不然绘制无效。 lineTo方法 功能:从x,y的位置绘制一条直线到起点或者上一个线头点。 语法:ctx.lineTo(x, y); 参数:x,y 线头点坐标。
stroke方法 功能:根据路径绘制线。路径只是草稿,真正绘制线必须执行stroke 语法:ctx.stroke(); 设置描边颜色:ctx.strokeStyle = "red";
canvas标签基本使用[HTML] 纯文本查看 复制代码 <canvas id="cvs" width="150" height="150"></canvas>
兼容性处理
[HTML] 纯文本查看 复制代码 <canvas width="600" height="400">
IE9及其以上版本的浏览器,才支持canvas标签
提示:您的浏览器不支持canvas,请升级浏览器
</canvas>
设置宽高的注意点如果你绘制出来的图像是扭曲的, 尝试用width和height属性为<canvas>明确规定宽高,而不是使用CSS。 closePath方法 功能:闭合路径,它尝试从当前点到起始点画一条直线来闭合路径,但如果当前路径已经闭合,此方法不会做任何的操作。 语法:ctx.closePath(); 注意:closePath方法并不是必须的,但是如果是绘制矩形或者三角形等需要闭合的路径时,可以使用。
fill方法 解释:填充,是将闭合的路径的内容填充具体的颜色, 默认黑色。 语法:ctx.fill(); 注意:如果当前路径没有闭合,使用fill方法时会自动调用closePath让路径闭合。 设置填充颜色:ctx.fillStyle = "red";
beginPath方法 功能:开启新路径,清空之前所有的路径 语法:ctx.beginPath(); 注意:stroke和fill方法会对当前画布中所有的路径进行绘制,如果不希望是这种效果,需要在适当的地方使用beginPath将路径给清空掉。
非零环绕原则(了解)使用fill方法对路径进行填充时,采用的是非零环绕原则(了解即可,通过我们很少会填充一个非常复杂的路径) 对于路径中的任意给定区域,从该区域内部画一条足够长的线段,使此线段的终点完全落在路径范围之外。 将计数器初始化为0, 每当这条线段与路径相交时,如果是路径是顺时针,计数器+1,如果是逆时针,计数器-1。 如果计数器的值最终是0,那么此区域不填充,如果技术的值最终不是0,那么此区域填充。
设置canvas绘制属性[JavaScript] 纯文本查看 复制代码 ctx.fillStyle = "red";
ctx.fillStyle = "rgb(255,0,0)";
ctx.fillStyle = "#f00";
[JavaScript] 纯文本查看 复制代码 ctx.strokeStyle = "red";
ctx.strokeStyle = "rgb(255,0,0)";
ctx.strokeStyle = "#f00";
[JavaScript] 纯文本查看 复制代码 //设置线宽为20
ctx.lineWidth = 20;
[JavaScript] 纯文本查看 复制代码 //参数:数组
// 10 --> 实线的长度
// 5 --> 虚线的长度
ctx.setLineDash([10, 5]);
[JavaScript] 纯文本查看 复制代码 //butt,默认值,没帽子
ctx.lineCap = "butt";
//round:圆帽子
ctx.lineCap = "round";
//square:方帽子
ctx.lineCap = "square";
[JavaScript] 纯文本查看 复制代码 //miter: 默认, 尖角
ctx.lineJoin = "miter";
//round: 拐角是圆的
ctx.lineJoin = "round";
//bevel: 斜角
ctx.lineJoin = "bevel";
1px线宽问题实际的2px的效果: 思考:如何绘制真正的1px的线??? 坐标应该是.5的地方
绘制矩形
绘制矩形路径rect功能:快速绘制一个矩形的路径 语法:ctx.rect(x, y, w, h); x:左顶点的x坐标 y:左顶点的y坐标 w:矩形的宽度 h:矩形的高度
注意:rect方法只是规划了矩形的路径,并没有填充和描边, 所以最后还是要调用 fill 或者 stroke 方法绘制
绘制描边矩形strokeRect功能:快速绘制一个描边矩形 语法:ctx.strokeRect(x, y, w, h); 注意:此方法会直接stroke绘制一个矩形,不会产生路径。
绘制填充矩形fillRect功能:快速绘制一个填充矩形 语法:ctx.fillRect(x, y, w, h); 注意:此方法会直接stroke绘制一个矩形,不会产生路径。
清除矩形clearRect-橡皮擦功能:清除某个矩形内的绘制内容,相当于画图中的橡皮擦 语法:ctx.clearRect(x, y, w, h); 清除整个画布:ctx.clearRect(0, 0, cvs.width, cvs.height);
绘制圆弧
圆弧:圆上任意两点间的部分叫做圆弧
arc方法 功能:创建一个圆弧的路径 语法:ctx.arc(x, y, r, startRadian, endRadian, counterclockwise) 注意:绘制的仅仅是路径,需要使用stroke或者fill进行绘制。 [JavaScript] 纯文本查看 复制代码 ctx.arc(200, 200, 150, 0, 1.5 * Math.PI, false);
弧度与角度一个圆的角度是360deg, 360deg = 2π 一弧度 约等于 57.3度 [JavaScript] 纯文本查看 复制代码 //角度/180 = 弧度/π
//角度转弧度
function toRadian(angle) {
return angle / 180 * Math.PI;
}
//弧度转角度
function toAngle (radian) {
return radian / Math.PI * 180;
}
绘制扇形[JavaScript] 纯文本查看 复制代码 //需求:在画布正中心,绘制一个扇形,圆心150,开始角度 90deg, 结束角度180deg, 顺时针
var x = cvs.width/2;
var y = cvs.height/2;
var r = 150;
//1. 将画笔移动到圆心
ctx.moveTo(x, y);
//2. 绘制圆弧(绘制圆弧会自动的从画笔处连一条线到圆弧开始处)
ctx.arc(x, y, r, toRadian(90), toRadian(180));
//3. 填充扇形
ctx.fill();
绘制文字
strokeText功能:绘制描边文字 用法:ctx.strokeText(text, x, y); text:文本内容 x:文本的x坐标 y:文本的y坐标
fillText功能:绘制填充文字 用法:ctx.fillText(text, x, y); text:文本内容 x:文本的x坐标 y:文本的y坐标
设置文字的样式例如: ctx.textBaseline = 'top';绘制图片
drawImage的使用用法
1 -基本使用context.drawImage(img, dx, dy); 参数:
img : 图片dom对象 x,y 绘制图片到画布中坐标
注意:使用drawImage时必须保证图片已经加载了
用法2-设置宽高context.drawImage(img, dx, dy, dWidth, dHeight); width:绘制到canvas中展示的宽度 注意:设置width和height时,为了图片不被拉伸,需要按比例设置
如果指定宽高,最好成比例,不然图片会被拉伸
等比公式: height = imgHeight / imgWidth * width;
设置高 = 原高度 / 原宽度 * 设置宽;
用法3-图片裁切context.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); 参数:
img:图片对象 sx, sy : 图片中的裁切位置 sWidth, sHeight :图片上的裁切范围 dx, dy : 图片在画布中的位置 dWidth, dHeight: 图片在画布中的大小。
创建img对象[JavaScript] 纯文本查看 复制代码 var img = new Image(); //这个就是 img标签的dom对象
img.src = "imgs/arc.gif";
img.alt = "文本信息";
img.onload = function() {
//图片加载完成后,执行此方法
}
变换
canvas中所有的变化都是相对于坐标系的变换
平移缩放旋转状态保存与恢复 每次绘制,都会读取绘图上下文对象中设置的属性。我们把上下文对象的这些属性值就可以理解为是状态。 Canvas 中引入了状态的保持机制.
使用 CanvasRenderingContext2D.save() 方法可以保存当前状态.
如果需要恢复到已经保存的状态, 只需要调用 CanvasRenderingContext2D.restore() 方法即可.
状态保持的机制是基于状态栈实现的. 也就是说 save 一次就存储一个状态.
restore 一次就将刚刚存入的恢复. 如果 save 两次, 就需要 restore 两次, 才可以恢复到最先的状态.
一般在封装绘图的时候都会采用开始绘制之前, save 一次, 然后 开启一个新路径 beginPath,
然后绘制结束后 restore, 这样保持当前状态不会对其他绘图代码构成影响.
绘制环境保存和还原
|