canvas入门之时钟的实现
canvas 入门之作:
三步实现一个时钟:
直接上效果:
- step 1 : 背景制作
首先制作从1-12的数字:var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = canvas.height = 400;
ctx.translate(200,200);
var R = 150;
ctx.font = "14px Helvetica";
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
for(var i=1;i<13;i++){
var radian = (i*30)*Math.PI / 180;
ctx.fillText(i,R*Math.sin(radian),R*(-Math.cos(radian)))
}关于 js 中Math.cos()和 Math.sin()的作用是这样的:
Math.sin(x) x 的正玄值。返回值在 -1.0 到 1.0 之间; Math.cos(x) x 的余弦值。返回的是 -1.0 到 1.0 之间的数; 这两个函数中的X 都是指的“弧度”而非“角度”,弧度的计算公式为: 2*PI/360*角度; 30° 角度 的弧度 = 2*PI/360*30;
效果图如下:

十分简单的绘出了背景; - step 2 : 绘出当前时间的指针位置
var getTime = function(){
var myDate = new Date();
return {
H:myDate.getHours(), //获取当前小时数(0-23)
M:myDate.getMinutes(), //获取当前分钟数(0-59)
S:myDate.getSeconds(), //获取当前秒数(0-59)
}
} var sDeg = 6*Math.PI / 180;
var dDeg = 30*Math.PI /180; var Animation = function(time){
ctx.strokeStyle = "#e20437";
ctx.moveTo(0,0);
ctx.lineTo(140*Math.sin(sDeg*time.S),140*(-Math.cos(sDeg*time.S)))
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "#000";
ctx.moveTo(0,0);
ctx.lineTo(100*Math.sin(sDeg*time.M),100*(-Math.cos(sDeg*time.M)));
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.moveTo(0,0);
ctx.lineTo(80*Math.sin(dDeg*time.H),80*(-Math.cos(dDeg*time.H)));
ctx.stroke();
}
var time = getTime();
Animation(time);因为秒针的颜色与时针,分针的不同,所以才用了 ctx.beginPath()多次;
效果图:
- step 3 :添加动画
给 canvas添加动画:var Animation = function(time){
ctx.clearRect(-200,-200,400,400);
printBG();
ctx.strokeStyle = "#e20437";
ctx.moveTo(0,0);
ctx.lineTo(140*Math.sin(sDeg*time.S),140*(-Math.cos(sDeg*time.S)))
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "#000";
ctx.moveTo(0,0);
ctx.lineTo(100*Math.sin(sDeg*time.M),100*(-Math.cos(sDeg*time.M)));
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.moveTo(0,0);
ctx.lineTo(80*Math.sin(dDeg*time.H),80*(-Math.cos(dDeg*time.H)));
ctx.stroke();
};
var time = getTime();
Animation(time);
setInterval(function(){
time.S += 1;
if(time.S>60){
time = getTime();
}
Animation(time);
},1000)为什么我会每60秒就获取一次时间呢?因为 setInterval 有一个众所周知的缺点,在时间计算方面随着时间的推移,会因为阻塞等等原因失去准确率,所以我这样做可以提高时间的准确,当然使用 webwork 应该也能解决问题;
其实在实现的过程中,大家都发现了连背景也要重新绘制,效率真的非常差,这正是原生 API 的不足之处,这个可以使用一些框架来进行解决;
另一种方法是,专门制作一个背景将两者重叠在一起;还有一个 api 是也可以解决这个问题的就是:ctx.clip(),这是可以在 canvas里扣下一部分画面,只在这里面绘图,不过碰到动画和背景相接触的就没有办法了,局限性比较大完整的代码我都放在了 GitHub 里:https://github.com/Grewer/JsDemo/tree/master/clock
demo 地址:https://grewer.github.io/JsDemo/clock/step3.html
canvas入门之时钟的实现的更多相关文章
- Canvas入门(2):图形渐变和图像形变换
来源:http://www.ido321.com/986.html 一.图形渐变(均在最新版Google中测试) 1.绘制线性渐变 1: // 获取canvas 的ID 2: var canvas = ...
- Canvas入门(1):绘制矩形、圆、直线、曲线等基本图形
来源:http://www.ido321.com/968.html 一.Canvas的基础知识 Canvas是HTML 5中新增的元素,专门用于绘制图形.canvas元素就相当于一块“画布”,一块无色 ...
- HTML5 canvas入门
HTML5 Canvas入门 <canvas> 标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形.在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字. ...
- 深夜,用canvas画一个时钟
深夜,用canvas画一个时钟 查看demo 这几天准备阿里巴巴的笔试,可以说已经是心力交瘁,自从阿里和蘑菇街的内推被刷掉之后,开始越来越怀疑起自己的能力来,虽然这点打击应该是微不足道的.毕竟校招在刚 ...
- canvas自适应圆形时钟绘制
前面的话 前面介绍过canvas粒子时钟的绘制,本文将详细介绍canvas自适应圆形时钟绘制 效果演示 最终自适应圆形时钟的效果如下所示 功能分析 下面来分析一下该圆形时钟的功能 [1]静态背景 对于 ...
- canvas 入门
<canvas>是HTML5新增的,是可以使用脚本(JavaScript)在其中绘制图像的HTML元素. canvas是由HTML代码配合高度和宽度属性而定义出的可绘制区域,JavaScr ...
- Canvas 入门案例
五. Canvas 入门案例 1. canvas 圆形绘制 <!DOCTYPE html> <html lang="en"> <head> ...
- Canvas入门笔记-实现极简画笔
今天学习了Html5 Canvas入门,已经有大神写得很详细了http://www.cnblogs.com/tim-li/archive/2012/08/06/2580252.html#8 在学习过后 ...
- canvas做的时钟,学习下
canvas标签只是图形容器,您必须使用脚本来绘制图形. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性.——获取上下文对象. getContext(" ...
随机推荐
- Keras学习环境配置-GPU加速版(Ubuntu 16.04 + CUDA8.0 + cuDNN6.0 + Tensorflow)
本文是个人对Keras深度学习框架配置的总结,不周之处请指出,谢谢! 1. 首先,我们需要安装Ubuntu操作系统(Windows下也行),这里使用Ubuntu16.04版本: 2. 安装好Ubunt ...
- 双向链表--Java实现
/*双向链表特点: *1.每个节点含有两个引用,previos和next,支持向前或向后的遍历(除头节点) *2.缺点插入或删除的时候涉及到引用修改的比较多 *注意:下面的双向链表其实也实现了双端链表 ...
- Linux文档的压缩与打包
linux系统中的后缀名其实要不要无所谓,但是对于压缩文件来讲必须要带上.这是为了判断压缩文件是由哪种压缩工具所压缩,而后才能去正确的解压缩这个文件.Linux压缩文件常见的后缀名所对应的压缩工具: ...
- jQrid常用操作(转帖)
转自: http://blog.csdn.net/zhcj3672/article/details/6944955 JqGrid相关操作备忘 方法列表 1.获得当前列表行数: $("#gri ...
- Dagger2 入门解析
前言 在为dropwizard选择DI框架的时候考虑了很久.Guice比较成熟,Dagger2主要用于Android.虽然都是google维护的,但Dagger2远比guice更新的频率高.再一个是, ...
- 【初学者必读】能让你月薪过万的5大web前端核心技能
前言Web前端开发所涉及的内容主要包括W3C标准中的结构.行为和表现,那么这三项中我们需要掌握的核心技能是什么呢?看小编来为你揭开谜底的. 1.开发语言 HTML发展历史有二十多年,历经多次版本更新, ...
- 安装jdk时出现java -version权限不够问题
今天在ubuntu上安装jdk的时候,最后测试java -version总是不行,出现了 bash: /home/jdk1.7.0_25/bin/java: 权限不够的问题 百度之后,在http:// ...
- MQTT——编写连接报文
笔者在上一章对连接报文进行了相关的讲解.这一章笔者想写一个连接报文的例子来加深理解.本来这一章也应该在上一章出现的.可是笔者怕太长了.不好方便阅.所以决定分俩章来.正如笔者上一章所讲的.笔者会用Net ...
- RxSwift 对 MJRefresh 使用的封装
对于一个很常用的两个库, MJRefresh 如何可以像 UIButton 使用方式呢: btn.rx.tap.subscribe(...) Rxswift 中的很多类似处理的方式都使用了跟下面极为相 ...
- A+B problems
这几道习题大概是ACM输入输出格式的普及 P1:---------------------------------------------------------------------------- ...