canvas绘图
该元素负责在页面中设定一个区域,然后由js动态地在这个区域中绘制图形。这个技术最早是由美国苹果公司推出的,目的是为了取代flash,很快主流浏览器都支持它。
绘制路径
要绘制路径首先必须调用beginPath()方法,如果想绘制一条连接到起点的线条则调用closePath()方法;如果路径已完成,你想用fillStyle填充它,可以调用fill()方法。另外还可以调用stroke()方法对路径描边,使用strokeStyle。
接口 | 参数 | 功能 |
---|---|---|
rect() | x,y,width,height | 从点x,y开始绘制一个矩形,宽和高分别由width和height指定,这个方法是绘制路径。而不是fillRect()和strokeRect()所绘制的独立形状 |
arc() | x,y,radius,startAngle,endAngle,counterclockwise 六个参数 | 以x,y为圆心绘制一条弧线,半径为radius,起始和结束角度分别为startAngle和endAngle,最后一个参数表示角度是否按逆时针方向计算,值为false表示顺时针。 |
lineTo() | x,y | 从上一点开始绘制一条直线,到x,y为止 |
moveTo() | x,y | 将绘图游标移动到x,y,不画线。 |
按照上图,就能画出圆,半圆,,四分之一圆等等。
开始画图
1.先设置一块画布。
<style>
.cvs {
border:solid 1px blue; //加一个边框更容易确定位置
display: block; //把canvas设置为块
margin: auto; //canvas居中显示
}
</style>
<canvas class="cvs" width="500px" height="500px"></canvas>
2.画一个圆,并将圆心坐标重新设为(0,0)
var c = document.getElementsByClassName('cvs')[0]
var cv = c.getContext('2d')
cv.translate(250, 250)
function yuan() {
cv.lineWidth = 10;
cv.beginPath()
cv.arc(0, 0, 245, 0, 2 * Math.PI, false)
cv.closePath()
cv.stroke()
}
3.在钟面上标上时间和刻度
function num() {
var nums = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
for (i = 0; i < nums.length; i++) {
var rad = 2 * Math.PI / 12 * i;
var x = Math.cos(rad) * 215;
var y = Math.sin(rad) * 215;
cv.font = "20px Georgia";
cv.textBaseline = 'middle';
cv.textAlign = "center";
cv.fillText(nums[i], x, y);
}
for (i = 0; i < 60; i++) {
var rad = 2 * Math.PI / 60 * i;
var x = Math.cos(rad) * 230;
var y = Math.sin(rad) * 230;
cv.beginPath();
if (i % 5 == 0) {
cv.fillStyle = '#000'
} else {
cv.fillStyle = '#ccc'
}
cv.arc(x, y, 2, 0, Math.PI * 2, false)
cv.closePath();
cv.fill()
}
}
4.开始画时针
function dHour(hour, minu) { //因为时针会随着分针的走动而走动,所以设置两个参数
cv.save();
cv.beginPath();
var rad = 2 * Math.PI / 12 * hour; //时针每小时走的角度
var rad2 = 2 * Math.PI / 12 / 60 * minu;
cv.lineWidth = 8;
cv.lineCap = 'round'
cv.rotate(rad + rad2) //时针走的角度
cv.moveTo(0, 10)
cv.lineTo(0, -115)
cv.stroke();
cv.restore();
}
5.画分针
function dMinu(minu) {
cv.save();
cv.beginPath();
var rad = 2 * Math.PI / 60 * minu;
cv.lineWidth = 5;
cv.lineCap = 'round'
cv.rotate(rad)
cv.moveTo(0, 10)
cv.lineTo(0, -160)
cv.stroke();
cv.restore();
}
6.画秒针,秒针的画法和分针基本上一样
function dSecd(secd) {
cv.save();
cv.beginPath();
var rad = 2 * Math.PI / 60 * secd;
cv.lineWidth = 3;
cv.lineCap = 'round'
cv.strokeStyle = "#f00";
cv.rotate(rad)
cv.moveTo(0, 10)
cv.lineTo(0, -200)
cv.stroke();
cv.restore();
}
7.在圆心画一个圆点,用来装饰
function center() {
cv.beginPath()
cv.arc(0, 0, 5, 0, 2 * Math.PI, false)
cv.fillStyle = "gray"
cv.fill()
}
8.让指针转动
function time() {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
// var cr = Math.floor(Math.random() * 256)
// var cg = Math.floor(Math.random() * 256)
// var cb = Math.floor(Math.random() * 256)
// document.querySelector('body').style.background = "rgb(" + cr + ',' + cg + ',' + cb + ')'; //网页背景每秒随机改变,可以不要
cv.clearRect(-250, -250, 500, 500); //每次都清除一下画布,不然每次指针转动都会留下轨迹
yuan()
num()
dHour(h, m)
dMinu(m)
dSecd(s)
center()//将前面函数全部调用
}
time()
setInterval(time, 1000);设置定时器,每秒调用一次
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>clock</title>
</head>
<body>
<style>
.cvs {
display: block;
margin: auto;
}
</style>
<canvas class="cvs" width="500px" height="500px"></canvas>
<script>
var c = document.getElementsByClassName('cvs')[0]
var cv = c.getContext('2d')
cv.translate(250, 250)
function yuan() {
cv.lineWidth = 10;
cv.beginPath()
cv.arc(0, 0, 245, 0, 2 * Math.PI, false)
cv.closePath()
cv.stroke()
}
function num() {
var nums = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
for (i = 0; i < nums.length; i++) {
var rad = 2 * Math.PI / 12 * i;
var x = Math.cos(rad) * 215;
var y = Math.sin(rad) * 215;
cv.font = "20px Georgia";
cv.textBaseline = 'middle';
cv.textAlign = "center";
cv.fillText(nums[i], x, y);
}
for (i = 0; i < 60; i++) {
var rad = 2 * Math.PI / 60 * i;
var x = Math.cos(rad) * 230;
var y = Math.sin(rad) * 230;
cv.beginPath();
if (i % 5 == 0) {
cv.fillStyle = '#000'
} else {
cv.fillStyle = '#ccc'
}
cv.arc(x, y, 2, 0, Math.PI * 2, false)
cv.closePath();
cv.fill()
}
}
// 时针
function dHour(hour, minu) {
cv.save();
cv.beginPath();
var rad = 2 * Math.PI / 12 * hour;
var rad2 = 2 * Math.PI / 12 / 60 * minu;
cv.lineWidth = 8;
cv.lineCap = 'round'
cv.rotate(rad + rad2)
cv.moveTo(0, 10)
cv.lineTo(0, -115)
cv.stroke();
cv.restore();
}
// 分针
function dMinu(minu) {
cv.save();
cv.beginPath();
var rad = 2 * Math.PI / 60 * minu;
cv.lineWidth = 5;
cv.lineCap = 'round'
cv.rotate(rad)
cv.moveTo(0, 10)
cv.lineTo(0, -160)
cv.stroke();
cv.restore();
}
// 秒针
function dSecd(secd) {
cv.save();
cv.beginPath();
var rad = 2 * Math.PI / 60 * secd;
cv.lineWidth = 3;
cv.lineCap = 'round'
cv.strokeStyle = "#f00";
cv.rotate(rad)
cv.moveTo(0, 10)
cv.lineTo(0, -200)
cv.stroke();
cv.restore();
}
// 圆心
function center() {
cv.beginPath()
cv.arc(0, 0, 5, 0, 2 * Math.PI, false)
cv.fillStyle = "gray"
cv.fill()
}
function time() {
var d = new Date();
var h = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
// var cr = Math.floor(Math.random() * 256)
// var cg = Math.floor(Math.random() * 256)
// var cb = Math.floor(Math.random() * 256)
// document.querySelector('body').style.background = "rgb(" + cr + ',' + cg + ',' + cb + ')';
cv.clearRect(-250, -250, 500, 500);
yuan()
num()
dHour(h, m)
dMinu(m)
dSecd(s)
center()
}
time()
setInterval(time, 1000);
</script>
</body>
</html>
相比太极图,时针难度的确是加大了不少。大家也可以继续在时钟的基础上加上更多的东西,让这个时钟变得更加美观。
希望大家在阅读完之后,有更简单的绘制方法,请在评论区留言,谢谢。