饼状图
arc(x,y,r,startAngle,endAngle,bool);
x 圆心横坐标
y 圆心纵坐标
r 半径
startAngle 开始角度
endAngle 结束角度
anticlockwise 是否逆时针方向绘制(默认false表示顺时针;true表示逆时针)
绘制文本
- ctx.font = ‘微软雅黑’ 设置字体
- strokeText()
- fillText(text,x,y,maxWidth)
- text 要绘制的文本
- x,y 文本绘制的坐标(文本左下角)
- maxWidth 设置文本最大宽度,可选参数(一般不设置)
- ctx.textAlign文本水平对齐方式,相对绘制坐标来说的
- left
- center
- right
- start 默认
- end
- ctx.direction属性css(rtl ltr) start和end于此相关
- 如果是ltr,start和left表现一致
- 如果是rtl,start和right表现一致
- ctx.textBaseline 设置基线(垂直对齐方式 )
- top 文本的基线处于文本的正上方,并且有一段距离
- middle 文本的基线处于文本的正中间
- bottom 文本的基线处于文本的证下方,并且有一段距离
- hanging 文本的基线处于文本的正上方,并且和文本粘合
- alphabetic 默认值,基线处于文本的下方,并且穿过文字
- ideographic 和bottom相似,但是不一样
- measureText() 获取文本宽度obj.width
制作动画
drawImage()
三个参数drawImage(img,x,y)
img 图片对象、canvas对象、video对象
x,y 图片绘制的左上角
五个参数drawImage(img,x,y,w,h)
img 图片对象、canvas对象、video对象
x,y 图片绘制的左上角
w,h 图片绘制尺寸设置(图片缩放,不是截取)
九个参数drawImage(img,x,y,w,h,x1,y1,w1,h1)
img 图片对象、canvas对象、video对象
x,y,w,h 图片中的一个矩形区域
x1,y1,w1,h1 画布中的一个矩形区域
坐标变换 - 平移 移动画布的原点
- translate(x,y) 参数表示移动目标点的坐标
- 缩放
- scale(x,y) 参数表示宽高的缩放比例
- 旋转
- rotate(angle) 参数表示旋转角度
饼状图案例
效果图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas2</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var PieLine = function (cxt) {
this.cxt = cxt || document.querySelector("canvas").getContext('2d');
this.canvasWidth = this.cxt.canvas.width;
this.canvasHeight = this.cxt.canvas.height;
//原点
this.x0 = this.canvasWidth / 2 + 60;
this.y0 = this.canvasHeight / 2;
//半径
this.radius = 150;
//延申出去的长度
this.outline = 20;
//长方形 的尺寸
this.ractW = 20;
this.ractH = 10;
this.space = 10;
}
//行为和方法
PieLine.prototype.init = function (data) {
this.drawPie(data);
}
//画圆
PieLine.prototype.drawPie = function (data) {
var that = this;
var beginAngle = 0;
that.formatDate(data).forEach(function (item, i) {
var endAngle = beginAngle + item;
that.cxt.beginPath();
that.cxt.moveTo(that.x0, that.y0);
that.cxt.arc(that.x0, that.y0, that.radius, beginAngle, endAngle);
var angleColor = that.cxt.fillStyle = that.randomColor();
that.cxt.fill();
that.drawTitle(beginAngle, item, angleColor, data[i].title);
that.drawRact(i, angleColor, data[i].title);
beginAngle = endAngle;
})
}
//标题
PieLine.prototype.drawTitle = function (beginAngle, angle, color, title) {
var edge = this.radius + this.outline;
var edgeX = Math.cos(beginAngle + angle / 2) * edge;
var edgeY = Math.sin(beginAngle + angle / 2) * edge;
this.cxt.beginPath();
this.cxt.moveTo(this.x0, this.y0);
this.cxt.lineTo(this.x0 + edgeX, this.y0 + edgeY);
this.cxt.strokeStyle = color;
this.cxt.stroke();
this.cxt.beginPath();
this.cxt.font = '12px Microsoft YaHei';
var strWidth = this.cxt.measureText(title).width;
this.cxt.textBaseline = 'bottom';
if (this.x0 > this.x0 + edgeX) {
this.cxt.moveTo(this.x0 + edgeX, this.y0 + edgeY);
this.cxt.lineTo(this.x0 + edgeX - strWidth, this.y0 + edgeY);
this.cxt.stroke()
this.cxt.fillText(title, this.x0 + edgeX - strWidth, this.y0 + edgeY);
} else {
this.cxt.moveTo(this.x0 + edgeX, this.y0 + edgeY);
this.cxt.lineTo(this.x0 + edgeX + strWidth, this.y0 + edgeY);
this.cxt.stroke();
this.cxt.fillText(title, this.x0 + edgeX, this.y0 + edgeY);
}
}
//绘制左上角的矩形
PieLine.prototype.drawRact = function (index, color, title) {
this.cxt.beginPath();
this.cxt.fillStyle = color;
this.cxt.fillRect(this.space, this.space + index * this.ractH + this.space / 2 * index, this.ractW, this.ractH);
this.cxt.beginPath();
this.cxt.font = '12px Microsoft YaHei';
this.cxt.textBaseline = 'top';
this.cxt.fillText(title, this.space * 1.5 + this.ractW, this.space + index * this.ractH + index * this.space / 2);
}
//data格式
PieLine.prototype.formatDate = function (data) {
var dataArr = [];
var total = 0;
var dataAngle = [];
data.forEach(function (item, i) {
total += item.num;
dataArr.push(item.num);
})
dataArr.forEach(function (item, i) {
dataAngle.push(Math.PI * 2 * (item / total));
})
return dataAngle;
}
//随机的颜色
PieLine.prototype.randomColor = function () {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return "rgb(" + r + "," + g + "," + b + ")"
}
var data = [
{title: '15岁-20岁', num: 18},
{title: '20岁-25岁', num: 16},
{title: '25岁-30岁', num: 32},
{title: '30岁-35岁', num: 15},
{title: '35岁-40岁', num: 19},
{title: '40岁-45岁', num: 43}
];
var pieLine = new PieLine();
pieLine.init(data);
</script>
</body>
</html>
制作用上下左右键控制的小人动画案例:
效果:
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>行走的小人</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var Person = function (cxt) {
this.cxt = cxt || document.querySelector("canvas").getContext("2d");
this.src = "image/03.png";
//画布的尺寸
this.canvasWidth = this.cxt.canvas.width;
this.canvasHeight = this.cxt.canvas.height;
this.spacX = 0;
this.spacY = 0;
//一次走10像素
this.spaceSize = 10;
}
//行为方法
Person.prototype.init = function () {
var that = this;
//加载图片
this.loadImage(function (image) {
//图片尺寸
that.imgWidth = image.width;
that.imgHeight = image.height;
that.personWidth = that.imgWidth / 4;
that.personHeight = that.imgHeight / 4;
that.x0 = that.canvasWidth / 2 - that.personWidth / 2;
that.y0 = that.canvasHeight / 2 - that.personWidth / 2;
//默认位置为中心点
that.cxt.drawImage(image, 0, 0, that.personWidth, that.personHeight, that.x0, that.y0, that.personWidth, that.personHeight);
//通过方向键来控制
that.index = 0;
window.onkeydown = function (e) {
//下
if (e.keyCode == 40) {
that.direction = 0;
that.spacY++;
that.drawImg(image);
//上
} else if (e.keyCode == 38) {
that.spacY--;
that.direction = 3;
that.drawImg(image);
//右
} else if (e.keyCode == 39) {
that.spacX++;
that.direction = 2;
that.drawImg(image);
//左
} else if (e.keyCode == 37) {
that.spacX--;
that.direction = 1;
that.drawImg(image);
}
}
})
}
Person.prototype.drawImg = function (image) {
this.cxt.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
this.index++;
this.cxt.drawImage(image, this.index * this.personWidth, this.direction * this.personHeight,
this.personWidth, this.personHeight,
this.x0 + this.spacX * this.spaceSize, this.y0 + this.spacY * this.spaceSize,
this.personWidth, this.personHeight);
console.log()
if (this.index >= 3) {
this.index = 0;
}
}
//加载图片
Person.prototype.loadImage = function (callback) {
var img = document.createElement("img");
img.onload = function () {
callback && callback(img);
}
img.src = this.src;
}
var person = new Person();
person.init();
</script>
</body>
</html>
坐标的变换案例:
效果
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>旋转</title>
<style>
canvas {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<script>
var cxt = document.querySelector("canvas").getContext('2d');
cxt.translate(150, 150);//坐标原点移动
setInterval(function () {
cxt.rotate(Math.PI / 180);//旋转
cxt.strokeRect(50, 50, 100, 100);//画图
}, 500)
</script>
</body>
</html>