小任务之Canvas绘制时钟
背景图的绘制(大圆、数字、小圆点)
掌握基础知识:圆的绘制(arc方法),关于圆的弧度的计算,数学中关于sin cos
的用法
圆的弧度为2*Math.PI
12个数字分得弧度每个为2*Math.PI/12
那么rad=i*2*Math.PI/12
x=Math.cos(rad)*所需要的长度(也就是半径-差值)
y=Math.sin(rad)*所需要的长度(也就是半径-差值)
同理可得60个点的绘制
60个数字分得弧度每个rad=i*2*Math.PI/60
x=Math.cos(rad)*所需要的长度(也就是半径-差值)
y=Math.sin(rad)*所需要的长度(也就是半径-差值)
<!DOCTYPE html>
<html> <head>
<meta charset="utf-8" /> <title>canvas练习</title> </head> <body>
<canvas id="prac" width="500" height="500" style="border:1px solid black"></canvas>
<canvas id="clock" width="500" height="500" style="border:1px solid black"></canvas>
<script>
var prac = document.querySelector("#prac");
var test = prac.getContext("2d");
test.moveTo(20, 25); //起点,但是绘制
test.lineTo(200, 25); //终点
test.stroke(); //绘制路径 test.beginPath();
test.lineWidth = "10";
test.rect(200, 200, 50, 50);
test.stroke(); test.beginPath();
test.rect(260, 200, 50, 50);
test.fill(); test.fillStyle = "rgb(200,0,0)";
test.lineWidth = "10"; //带填充的,画线粗细无作用
test.fillRect(100, 100, 55, 50); //带填充的矩形 test.strokeStyle = "blue";
test.lineWidth = "1";
test.strokeRect(85, 85, 100, 150); //不带填充的矩形 test.beginPath();
test.arc(100, 295, 15, 0, 2 * Math.PI); //圆心坐标+半径+起始角和结束角;
test.stroke(); test.beginPath();
test.arc(150, 295, 15, 0, 2 * Math.PI); //圆心坐标+半径+起始角和结束角;
test.fill(); test.font = "20px Arial";
test.textAlign = "center";
test.fillText("Hello World", 400, 200);
test.textAlign = "center";
test.textBaseline = "hanging";
test.fillText("Hello World", 400, 200); //以下为时钟部分
var clock = document.getElementById("clock");
var ctx = clock.getContext("2d");
var width = clock.width;
var height = clock.height;
var radius = width / 2; //半径
var rem = width / 200; //画面比例 function drawBG() {
ctx.save(); //保存当前环境
ctx.translate(width / 2, height / 2);//转换原点为中心
ctx.beginPath();
ctx.lineWidth = 8 * rem;
//以0,0为原点,r为半径,0为起始角,2*Math.PI为结束角,顺时针画圆
ctx.arc(0, 0, radius - ctx.lineWidth / 2, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.stroke(); var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
//画出1-12的数字
hourNumber.forEach(function (number, i) {
var rad = 2 * Math.PI / 12 * i;
var x = Math.cos(rad) * (radius - 35 * rem);
var y = Math.sin(rad) * (radius - 35 * rem);
ctx.font = 20 * rem + "px Arial"; //拼接字符串
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(number, x, y);
})
//画出秒针走动的60个点
for (let i = 0; i < 60; i++) {
var rad = 2 * Math.PI / 60 * i;
var x = Math.cos(rad) * (radius - 18 * rem);
var y = Math.sin(rad) * (radius - 18 * rem);
ctx.beginPath();
if (i % 5 === 0) {
ctx.fillStyle = "#000";
ctx.arc(x, y, 3 * rem, 0, 2 * Math.PI);
} else {
ctx.fillStyle = "#ccc";
ctx.arc(x, y, 3 * rem, 0, 2 * Math.PI);
}
ctx.fill();
} }
//绘制时针
function drawHour(hour, minute) {
ctx.save();
ctx.beginPath();
var rad = 2 * Math.PI / 12 * hour;
var mrad = 2 * Math.PI / 12 / 60 * minute; //分60等份弧度
ctx.rotate(rad + mrad); //时针特殊性+上对应每分钟占的时钟刻度
ctx.moveTo(0, 10 * rem);
ctx.lineWidth = 6 * rem;
ctx.lineCap = "round";
ctx.lineTo(0, -radius / 2);
ctx.stroke();
ctx.restore();
}
//绘制分针
function drawMinute(minute) {
ctx.save();
ctx.beginPath();
var rad = 2 * Math.PI / 60 * minute;
ctx.rotate(rad);
ctx.moveTo(0, 10 * rem);
ctx.lineWidth = 3 * rem;
ctx.lineCap = "round";
ctx.lineTo(0, -radius + 45 * rem);
ctx.stroke();
ctx.restore();
}
//绘制秒针
function drawSecond(second) {
ctx.save();
ctx.beginPath();
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 * rem, -radius + 18 * rem);
ctx.lineTo(-1 * rem, -radius + 18 * rem);
ctx.fillStyle = "red";
ctx.fill();
ctx.restore();
}
//画时钟上的中心白色原点
function drawDot() {
ctx.beginPath();
ctx.arc(0, 0, 2 * rem, 0, 2 * Math.PI, false);
ctx.fillStyle = "white";
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();
console.log(hour, minute, second);
drawBG();
drawHour(hour, minute);
drawMinute(minute);
drawSecond(second);
drawDot();
ctx.restore(); //清除,起始坐标回到0,0
}
draw();//提前先画一次,避免空白
setInterval(draw, 1000); //每秒执行一次
</script>
</body> </html>
注意点:
1.rem=width/200(基准值)
所需要的像素换算=x*rem
2.canvas的字体设置可以用拼接字符串来动态根据rem修改大小:
ctx.font = 20 * rem + "px Arial"; //拼接字符串
3.为了使文字填充为该坐标中心, 那么利用文字对齐方式调整至中心位置
ctx.textAlign = "center";
ctx.textBaseline = "middle";
4.记得保存和重置,因为清除画布(不清除画布,画面会重叠)需要把坐标移动至左上角原始位置,所以本来我们画背景的时候将画布原点移致画布中心,所以要ctx.restore()
5.moveTo和lineTo都是不绘制的,最后得stroke(),或者fill()
6.由于时针的特殊性,所以要加上分钟走过的弧度来确定指针指向的位置
var rad = 2 * Math.PI / 12 * hour;
var mrad = 2 * Math.PI / 12 / 60 * minute; //分60等份弧度
ctx.rotate(rad + mrad); //时针特殊性+上对应每分钟占的时钟刻度
7.时分秒针以及中心原点的绘制,其中时针和分针就是绘制一个直线即可,秒针则画一个梯形样式呈现又粗到细的效果,要掌握的基础知识:直线的绘制,旋转角度的控制(rotate以弧度为单位),时钟的动态走动效果,则用setInterval
函数控制每一秒钟执行一次绘制时钟的函数。
小任务之Canvas绘制时钟的更多相关文章
- 使用canvas绘制时钟
使用canvas绘制时钟 什么使canvas呢?HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.<canvas> 标签只是图 ...
- 小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)
小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像) 微信小程序生成特色头像,海报等是比较常见的.下面我来介绍下实现该类小程序的过程. 首先选择前端来通过 canvas 绘制.这样比较节 ...
- Canvas绘制时钟
①首先在HTML的body标签中添加一个canvas标签,用于绘制时钟. <canvas id="myCanvas" width="600" height ...
- HTML5 之Canvas 绘制时钟 Demo
<!DOCTYPE html> <html> <head> <title>Canvas 之 时钟 Demo</title> <!--简 ...
- html5 Canvas绘制时钟以及绘制运动的圆
1.绘制时钟 <!-- js代码 --> <script type="text/javascript"> window.onload=function(){ ...
- 用canvas绘制时钟
用canvas做时钟其实很简单,下面是我做出的效果: 是不是还挺漂亮的? 下面上代码: html <div class="whole"> <canvas id=& ...
- HTML5 Canvas 绘制时钟
网上会看到很多绘制的时钟,看代码也是云里雾里,自学了下Canvas,觉得不难,就自己做了一个. 先看一下截图: 比较简陋,但是该有的都有了,样式只加了个阴影. html代码就不贴了,就一个canvas ...
- 使用canvas绘制时钟 (http://heeroluo.net/Article/Detail/95)
准备工作 在HTML中指定一个区域放置时钟: <div id="clock" style="position: relative;"></di ...
- canvas绘制时钟及注释及save和restore的用法
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
随机推荐
- TCP 的保活定时器
引言 可以没有任何数据流过一个空闲的 TCP 连接. 这意味着我们可以启动一个客户与服务器建 立一个连接,然后离去数小时.数天.数个星期或者数月,而连接依然保持.中间路由器可以崩溃和重启,电话线可以被 ...
- CSS 两个行内块元素,宽度相加刚好等于父盒子容器的元素,但第二个元素掉在第二行解决办法
我们可以发现:两个行内块元素,宽度相加刚好等于父盒子容器的元素,但第二个元素掉在第二行,这是什么问题呢? 我们先来看一下效果: <!DOCTYPE html> <html lang= ...
- Android Fragment原理及应用
1.Fragment简介 Fragment(片段) 表示 Activity 中的行为或用户界面部分.您可以将多个片段组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中 ...
- 第二章C++实验
2-28 (1)用if else 语句 #include<iostream> using namespace std; int main(){ char alphabet; while ( ...
- Linux云服务器下Tomcat部署
基于阿里云Centos 7服务器的Tomcat 项目部署 工具:一台安装jdk1.8的Centos 6/7.X 云服务器(64位) Putty ssh远程连接云服务器的软件 FileZillaCli ...
- 移动端滑动时页面惯性滑动overflow-scrolling: touch
-webkit-overflow-scrolling:auto | touch; auto: 普通滚动,当手指从触摸屏上移开,滚动立即停止 touch:滚动回弹效果,当手指从触摸屏上移开,内容会保持一 ...
- vscode用yuml画类图
vscode用yuml画类图 最近在找画类图的工具,发现vscode一款插件很好用,还支持markdown.vscode插件中直接搜索yuml安装即可. 文件后缀.yuml. 文件开头第一行这样写// ...
- 溶解shader
玩神界原罪2,感觉人物被建筑遮挡时,建筑的“溶解”效果很有意思,想实现一下.然后发现连溶解都没实现过,emmmmm....先来把溶解实现了~ 原理就是根据一张噪声图的值是否大于某个阈值,来判断是否丢弃 ...
- AR和VR的区别到底在哪?
AR是Augmented Reality的字母缩写,中文名字是“增强现实”,是一种全新人机交互技术.通过AR技术,让参与者与虚拟对象进行实时互动,从而获得一种奇妙的视觉体验,而且能够突破空间.时间以及 ...
- 性能测试工具Jmeter13-Jmeter跨线程组调用token
1.正则表达式或者json提取器(我是用json提取器提取的),提取token 2.添加后置处理器BeanShell PostProcessor,然后输入以下函数 3.添加HTTP信息头管理器,写入函 ...