canvas
< canvas>标签其实就相当于一个容器,一个可以展示绘图内容的画板。我们需要通过 js 脚本往里面绘制图形。Canvas 只能展示绘图的内容, 但是不能进行绘图。最早是 苹果公司 提出的该标签。(游戏 、可视化数据(图表)、banner 广告)
1) 使用 canvas 标签, 即可在页面中开辟一格区域. 可以设置其 width 和 height 设置该区域的尺寸。
2) 默认 canvas 的宽高为 300 和 150。
- 使用 属性设置 canvas 标签的宽高, 实际上相当于增加了 canvas 画布的像素。
- 但是如果使用 CSS 来设置画布的大小, 那么不会增加像素点, 只是将像素扩大了。
3)不要使用 CSS 的方式设置宽高, 应该使用 HTML 属性。
4)如果浏览器不支持 canvas 标签, 那么就会将其解释为 div 标签. 因此常常在 canvas 中嵌入文本, 以提示用户浏览器的能力。
<canvas id="myCanvas" width="600px" height="530px">
你的浏览器不支持canvas
</canvas>
若浏览器不支持此属性则会显示“你的浏览器不支持canvas”
canvas不是块级元素,在设置其居中的时候,要么外层包一个div,要么设置body{text-align:center;}。
5)canvas 的兼容性非常强, 只要支持该标签的, 基本功能都一样, 因此不用考虑兼容性问题。
6)canvas 本身不能绘图. 是使用 JavaScript 来完成绘图. canvas 对象提供了各种绘图用的 api。
- 第一篇 基本语法和使用
基本使用
// 获得 canvas 对象
var canvas = document.createElement( 'canvas' );
// 获得 CanvasRenderingContext2D 对象
var context = canvas.getContext( '2d' );
1)获得 canvas 对象
2)调用 getContext 方法, 提供字符串参数 ‘2d’
- 该方法返回 CanvasRenderingContext2D 类型的对象. 该对象提供基本的绘图命令
使用 CanvasRenderingContext2D 对象提供的方法进行绘图
如果要绘制 立体的图形需要传入 ‘webgl’
3)基本绘图命令
设置开始绘图的位置: context.moveTo( x, y ).
设置直线到的位置: context.lineTo( x, y ).
描边绘制: context.stroke(). //该方法用于连线, 将描述的所有点按照指定顺序连接起来
填充绘制: context.fill(). // 将开始的起点, 与最终的点连接起来, 构成一个闭合的图形, 并在里面填充颜色(默认黑色)
闭合路径: context.closePath(). // 使用该方法可以将最后一个描点与最开始的描点自动连接起来如果要绘制 立体的图形需要传入 'webgl', 返回 WebGLRenderingContext 类型的对象 绘制 平面图形的 对象是 CanvasRenderingContext2D 类型的('2d')
2)开始绘图
<canvas id="canvas" width="500px" height="400px">
你的浏览器不支持canvas
</canvas>
<script>
var canvas = document.getElementById( 'canvas' );
var context = canvas.getContext( '2d' );
//canvas.width = 500;
//canvas.height = 400;
canvas.style.border = '1px dashed red';
context.moveTo( 0, 0 );
context.lineTo( 500, 400 );
context.moveTo( 0, 400 );
context.lineTo( 500, 0 );
context.stroke();
</script>
非零环绕原则
如果需要判断某一个区域是否需要填充颜色
就从该区域中随机的选取一个点,从这个点拉一条直线出来, 一定要拉到图形的外面。
此时以该点为圆心,看穿过拉出的直线的线段. 如果是顺时针方向就记为 +1, 如果是 逆时针方向,就记为 -1.。
最终看求和的结果. 如果是 0 就不填充. 如果是 非0 就填充
闭合路径
closePath()
closePath 与 直接使用 lineTo 闭合是有区别的
Canvas 中绘图是有状态的
Canvas 绘图是含有状态的, 在需要改变颜色, 绘制方法, 改变一些属性... 就需要
改变绘图状态. 使用 beginPath() 方法. 开启一个新的路径,绘制另一个区域
虚线
ctx.setLineDash( 数组 ) //使用数组描述实线与虚线的长度
ctx.getLineDash() //获得线段样式数组
ctx.lineDashOffset = 值 //用于设置开始绘制虚线的偏移量. 数字的正负表示左右偏移
数组中存储的数字就是分别表示 实线部分与空白部分的长度 [ 10 ]
如何设置描边与填充的颜色
ctx.font=’45px 黑体’; // 这项设置必须在其他设置之前,初始化。
ctx.strokeStyle 设置描边的颜色 //stroke 绘制描边文字, 文字内空心
ctx.fillStyle 设置填充的颜色 // fill 绘制填充文字, 即实心文字
ctx.lineWidth 设置绘制图形的线宽 // ctx.lineWidth = 10
ctx.lineCap 设置线型末端的样式 // ctx.lineCap = ‘round’; //square
将直线进行封装
function Line(config) {
this.ctx = config.ctx;
this.x0 = config.x0;
this.y0 = config.y0;
this.x1 = config.x1;
this.y1 = config.y1;
this.ctx.strokeStyle = config.strokeStyle;
this.ctx.lineWidth = config.lineWidth;
}
Line.prototype = {
constructor: Line,
stroke: function() {
this.ctx.moveTo(this.x0, this.y0);
this.ctx.lineTo(this.x1, this.y1);
if (this.strokeStyle) {
this.ctx.strokeStyle = this.strokeStyle;
}
if (this.lineWidth) {
this.ctx.lineWidth = this.lineWidth;
}
this.ctx.stroke(); //调用stroke()方法 连线描边
}
};
var line = new Line({ x0, y0, x1, y1 });
line.stroke();
- 第二篇 绘制图形和文字
绘制形状
-> 矩形
ctx.rect( x, y, width, height ) //矩形路径 描边, 需要 stroke 或 fill
ctx.strokeRect( x, y, w, h )
ctx.fillRect( x, y, w, h )
ctx.clearRect( x, y, w, h ) 清除该矩形区域的内容
-> 清除整个画布
ctx.clearRect( 0, 0, cas.width, cas.height );
-> 圆弧
ctx.arc( x, y, r, startAngle, endAngle, clockwise )
弧度制
2 PI / 360° = 弧度 (radian)/ 对应的角度(angle)
function toAngle ( radian ) {
return radian * 180 / Math.PI;
}
function toRadian ( angle ) {
return angle * Math.PI / 180;
}
角度的坐标
水平向右的角度是 0 度, 或 0 弧度
顺时针是正方向, 逆时针是负方向
ctx.arc( x, y, radius, startAngle, endAngle, anticlockwise )
描述:
该方法用于绘制一段弧, 配合开始点的位置 与 stroke 方法或 fill 方法可以绘制扇形
方法中的前两个参数 x, y 表示绘制圆弧的圆心坐标
参数 radius 表示圆弧半径
参数 startAngle 与 endAngle 表示开始到结束的角度. 角度以水平向右为 0 弧度, 顺时针为正方向
参数 anticlockwise 表示是否采用默认的正向角度, 如果传入 true 表示逆指针为正 (该参数可选)
绘制文字
ctx.fillText( 文本内容, x, y )
ctx.strokeText( 文本内容, x, y );
常用的属性
ctx.font = '30px 黑体'
ctx.textAlign left, center, right start( 默认 ), end
ctx.textBaseline top, middle, bottom
ctx.measureText( 文本 ) 获取当前文字的字体设置下, 文字的宽度对象
ctx.font = '30px 黑体';
ctx.textAlign = 'left';
ctx.fillText( 'left', 150, 150 );
ctx.textAlign = 'right'
ctx.fillText( 'right', 150, 150 );
绘制饼图