基本使用:
1.Canvas 标签. 默认 300 * 150 的区域
2.利用 html 属性为它设置宽高. 不要使用 CSS 来设置.
使用 属性设置 canvas 标签的宽高, 实际上相当于增加了 canvas 画布的像素
但是如果使用 CSS 来设置画布的大小, 那么不会增加像素点, 只是将像素扩大了
3.Canvas 只能展示绘图的内容. 但是不能进行绘图
使用语法 canvas.getContext( ‘2d’ ) 就返回一个在当前画布上绘图的工具集
4.开始绘图,绘图的基本方法:
- 移动到开始位置
- moveTo(x,y)
- 开始画线条
- lineTo(x,y)
- 描边显示
- stroke()
- 描边颜色:.strokeStyle = ‘颜色’: 描边之前设置颜色
- 描边宽度:.lineWidth = 数值
- 闭合路径:.closePath(),可以省去最后一条边的绘
- 清除路径.beginPath();为了放置重绘
- 填充:.fill() 不定义填充,定义填充颜色也不起作用
- 填充颜色.fillStyle = ‘颜色’
- 如果先填充后描边,描边宽度正常
- 先描边,后填充,描边宽度会显示一半
- 非零环绕原则:判断哪些区域属于路径内
a) 在路径包围区域中,早一点没想外发射一条射线
b) 和所有环绕他的边相交
c) 开启一个计数器,从0计数
d) 如果这个设下遇到顺时针环绕,+1
e) 遇到逆时针环绕-1
f) 计算结果非0,即在路径内
- 先填充,后描边,才能显示设置的宽度
- 线帽样式:.lineCap =
a) butt(默认值)
b) round:圆头,半径为线宽的一半
c) square:方头(各突出线宽的一半)
- 交点样式:.lineJoin =
a) miter:默认尖角
b) round:圆角
c) bevel:平角’
- 画一条矩形路径:.rect(starX,starY,width,height)
- 只是路径,要在后面描边stroke();
- 绘制一个描边矩形:strokeRect(starX,starY,width,height)
- 绘制一个填充矩形:fillRect(starX,starY,width,height)
- 清除画布.clearRect(starX,starY,width,height)
- setLineDash([实线长度,虚线长度])
- getLineDash()获取如何设置的线条规则
- lineDashOffset = 3 偏移量
画弧
- arc(圆心X坐标,圆心Y坐标,半径,起点弧度,结束点弧度,[是否逆时针画])
- arc会从上次的结束点到弧的开始点之间画条直线
文字API
- strokeText(文字,参考X坐标,参考Y坐标[,限制文字最大长度])
- font = ‘加粗 字号/行高 字体’:设置字体样式
- a) 单独设置字号不可以,必须加字体样式才会生效
- fillText(文字,参考X坐标,参考Y坐标[,限制文字最大长度])
- textAlign = ‘left/right/start’对齐方式
- textBaseline = ‘top/middle/bottom/默认基线(alphabetic)
绘制图像
- drawImage()
a) 三种使用方式
1. 三个参数
a) .drawImage(获取标签,坐标X,坐标Y)
b) img.onload = function(){}:img加载完毕之后触发
2. 五个参数:把图片放置到指定位置,并指定宽高
a) .drawImage(获取标签,坐标X,坐标Y,width,height)
3. 九个参数:把裁剪后的图片放到指定的位置,并且知道大小
a) .drawImage(获取标签,裁剪图片的位置X, 裁剪图片的位置Y, 裁剪图片的width, 裁剪图片的height,坐标X,坐标Y,width,height)
- save();状态保存
- a) 把当前的状态(绘制环境的所有属性)复制一份保存
- restora();状态回滚
状态的保存与回滚
a) 把最近保存的一次状态作为当前状态
b) 回滚一次会把上次保存的属性删除
1. 再回滚会拿到上次保存的属性
c) 可多次回滚,依次往回找保存的属性
平移,旋转,缩放
- translate(X平移的量,Y轴平移的量)
- rotate(旋转的弧度)
- scale(X轴缩放比值,Y轴缩放比值)
- 角度转弧度:Math.PI / 180 * deg (deg是要转换的角度)
var s = Math.floor( Math.randow() * (max-min+1) + min ); //生成min-max之间的随机数
基本饼形图
var arc = {};
arc.toAngle = function (radian) {
return radian*180/Math.PI;
};
arc.toRadian = function (angle) {
return angle*Math.PI/180;
};
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width=600 height=600></canvas>
</body>
<script src="../Angle-radian.js"></script>
<script>
var cas = document.getElementsByTagName("canvas")[0];
var ctx = cas.getContext("2d");
var x0 =cas.width/2;
var y0 =cas.height/2;
var radius =100;
var colors = "red,blue,green,pink".split(",");
var startAngle = -90;
var data = [12,23,48,24];
var sum =0;
var data2 ;
data.forEach(function (v) {
sum+=v;
});
data2 = data.map(function (v) {
return {value:v,angle:v*360/sum}
});
// console.log(data2);
var oldAngle = null,
textAngle = null,
textX,
textY;
data2.forEach(function (v, i) {
ctx.beginPath();
ctx.moveTo(x0,y0);
oldAngle = startAngle;
textAngle = oldAngle + v.angle/2;
ctx.arc(x0,y0,radius,arc.toRadian(startAngle),arc.toRadian(startAngle+= v.angle));
ctx.fillStyle = colors[i];
ctx.fill();
// 开启文字路径
ctx.beginPath();
// 定位
textX = x0+(radius+20)*Math.cos(arc.toRadian(textAngle));
textY = y0+(radius+20)*Math.sin(arc.toRadian(textAngle));
// 绘制底线
ctx.moveTo(textX,textY);
ctx.lineTo((textX+20*Math.cos(arc.toRadian(textAngle))),(textY+20*Math.sin(arc.toRadian(textAngle))));
ctx.lineTo(textX<(textX+20*Math.cos(arc.toRadian(textAngle)))?(30+textX+20*Math.cos(arc.toRadian(textAngle))):(textX+20*Math.cos(arc.toRadian(textAngle)))-30,(textY+20*Math.sin(arc.toRadian(textAngle))));
ctx.strokeStyle = colors[i];
ctx.stroke();
// 绘制文字
// 设置字体的样式
if(textAngle>90&&textAngle<270){
ctx.textAlign = "right";
}
ctx.font="20px 黑体";
ctx.fillText(""+(v.angle/360*100).toFixed(0)+"%",textX+20*Math.cos(arc.toRadian(textAngle)),textY+20*Math.sin(arc.toRadian(textAngle))-10);
});
</script>
</html>
上面的代码写的太多繁杂,这里可以使用Konva框架帮助我们完成基本图形的绘制。
常用的图像框架有很多:
KonvaJS
百度的 echarts
D3.js
webgl 引擎
konva的基本理念:
任何图形都存在于舞台中( Konva.Stage ). 这个舞台中又可以包多个用户层( Konva.Layer ).
每一个层中都含有两个 <canvas> 着色器: 一个前台渲染器, 一个后台渲染器. 前台渲染器是可以看见的部分, 而后台渲染器是一个隐藏的 canvas. 后台渲染器为了提高效率实现事件监听的工作.
每一个层可以包含形状( Shape ), 形状的组( Group ), 甚至是由组组成的组. 舞台, 层, 组, 以及形状都是虚拟的节点( node ). 类似于 HTML 页面中的 DOM 节点.
konva的基本使用:
需要引入 Konva.js 文件
<script src="konva.js"></script>
然后页面中放置一个容器作为 Konva 处理的对象. Konva 会在该容器中添加 canvas 标签. 值得说明的是, 需要为这个标签添加 id 属性.
<div id="dv"></div>
然后编写 js 代码. Konva 是一个完全面向对象的库.
创建舞台
var stage = new Konva.Stage({
container: 'dv',
width: window.innerWidth,
height: window.innerHeight
});
//舞台中可以放置一个到多个层( Layer ), 所有的图形应该放在在层中.
//首先创建层对象. 层对象不需要传递参数.
var layer = new Konva.Layer();
//将层添加到舞台中. Konva 中凡是添加, 都是使用 add 方法.
stage.add( layer );
//在层中放置一个矩形, 就创建一个 矩形对象.
var rect = new Konva.Rect({
x: 100,
y: 50,
width: 200,
height: 100,
fill: 'red'
});
//Konva 中添加颜色使用 fill 属性和 stroke 属性, 分别表示填充颜色与描边颜色.
//将矩形添加到 层中
layer.add( rect );
//最后绘图使用 draw 方法
layer.draw();
只是简单记录下使用的理念和方法,具体的API就查看官网。