- HTML
没有添加任何图片的canvas时钟,内涵详细注释,放大canvas画布时,时针会随着比例进行变大缩小
<canvas id="clock" width="200px" height="200px"></canvas>
2.
* { margin:0; padding:0; } canvas { display:block; margin:200px auto; }
3.JS
var dom = document.getElementById('clock'); var ctx = dom.getContext('2d'); var width = ctx.canvas.width; var height = ctx.canvas.height; var r = width / 2; var rem = width / 200; //无论canvas画布多大 时钟都会随着比例变化 function drawBackground() { ctx.save(); //保存当前画布 以便使用clearRect() /*****************绘制背景圆****************************/ ctx.translate(r, r); //把绘图的中心移动到坐标为(r,r)的位置 ctx.beginPath(); //开始绘图 ctx.lineWidth = 10 * rem; //线条宽度 ctx.arc(0, 0, r - ctx.lineWidth / 2, 0, 2 * Math.PI, false); //绘制一个圆坐标为刚刚移动到的位置 因为半径为canvas正方形的一半所以半径要减去线条宽度的一半 ctx.stroke(); //绘制 /****************绘制小时点********************************/ var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]; //定义一个小时点数组 因为圆的起点是90度那个位置开始的 ctx.font = 18 * rem + 'px Arial'; //设置字体大小 ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; //设置文本的对齐方式 文本对齐居中 文本基线居中对齐 hourNumber.forEach(function(number, i) { //遍历并获取该数组 传入参数 一个为数字 一个是索引 var rad = 2 * Math.PI / 12 * i; //定义弧度 12个数字 相差就是 2*Math.PI / 12 这就是每个小时数的弧度 再乘以索引以对应弧度的计算 var x = Math.cos(rad) * (r - 30 * rem); //求x坐标 用cos方法 在乘以半径 因为小时点的半径肯定会小一些所以就半径也要小一点 var y = Math.sin(rad) * (r - 30 * rem); //求y坐标 方法同上 ctx.fillText(number, x, y); //填充文本 第一个参数是 文本 第二,三个为坐标 }); /************绘制分钟点**********************/ for (var i = 0; i < 60; i++) { //利用for循环遍历60个点 var rad = 2 * Math.PI / 60 * i; //定义弧度60个点 var x = Math.cos(rad) * (r - 18 * rem); //定义x坐标的位置 方法同上 var y = Math.sin(rad) * (r - 18 * rem); //定义y坐标的位置 方法同上 ctx.beginPath(); //因为上面有过beginPath所以需要重新绘制 if (i % 5 === 0) { //因为小时点是每隔5个就有一个所以 如果i取余等于0 就是小时数 小时点的样式带啊如下 ctx.fillStyle = "black" ctx.arc(x, y, 2 * rem, 0, 2 * Math.PI, false); //绘制圆 半径为2像素 } else { //反过来就是这样 ctx.fillStyle = "#ccc"; ctx.arc(x, y, 2 * rem, 0, 2 * Math.PI, false); //绘制圆 半径为2像素 } ctx.fill(); //因为需要实心圆 所以需要填充 } } /****************绘制时针*************/ function drawHour(hour, minute) { //绘制时针 ctx.save(); //save()和restore连用 表示先将其绘图环境保存起来 restore返回之前保存的状态 ctx.beginPath(); var rad = 2 * Math.PI / 12 * hour; //设置时针的位置 定义弧度 var mrad = 2 * Math.PI / 12 / 60 * minute; //因为时间在4:30的时候时针应该会在4-5之间 所以我们需要计算其当时的弧度 ctx.rotate(rad + mrad); //旋转至该弧度 加上分针中间的弧度 所以时针的弧度等于 时针的弧度加上分针的弧度 ctx.lineCap = 'round'; //绘制线条为圆头 ctx.lineWidth = 5 * rem; ctx.moveTo(0, 10 * rem); //移动圆点 因为时针需要多点尾巴出来所以定义到10; ctx.lineTo(0, -r / 2); //添一个点,将其链接到这个位置 ctx.stroke(); ctx.restore(); } /*************绘制分针******************/ function drawMinute(minute) { //绘制分针方法与时针方法类似 ctx.save(); ctx.beginPath(); var rad = 2 * Math.PI / 60 * minute; ctx.rotate(rad); ctx.lineWidth = 3 * rem; ctx.lineCap = 'round'; ctx.moveTo(0, 10 * rem); ctx.lineTo(0, -r + 30 * rem); ctx.stroke(); ctx.restore(); } /*******绘制秒针****************/ function drawSecond(second) { ctx.save(); ctx.beginPath(); ctx.fillStyle = '#f00'; var rad = 2 * Math.PI / 60 * second; ctx.rotate(rad); ctx.moveTo(-2 * rem, 20 * rem); //绘制秒针的线条 一头大 一头小 ctx.lineTo(2 * rem, 20 * rem); ctx.lineTo(1, -r + 18 * rem); ctx.lineTo(-1, -r + 18 * rem); ctx.fill(); //绘制线条颜色 ctx.restore(); } /************绘制中心圆点*************/ function drawDot() { ctx.beginPath(); ctx.fillStyle = "#fff"; ctx.arc(0, 0, 3 * rem, 0, 2 * Math.PI, false); ctx.fill(); } function draw() { ctx.clearRect(0, 0, width, height); //设置计时器每秒调用一次 但是因为调用后 之前的还会存在所以需要每秒清除画布 var now = new Date(); var hour = now.getHours(); var minute = now.getMinutes(); var second = now.getSeconds(); drawBackground(); drawHour(hour, minute); drawMinute(minute); drawSecond(second); drawDot(); ctx.restore(); } setInterval(draw, 1000);
效果图: