背景图的绘制(大圆、数字、小圆点)

掌握基础知识:圆的绘制(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绘制时钟的更多相关文章

  1. 使用canvas绘制时钟

    使用canvas绘制时钟  什么使canvas呢?HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.<canvas> 标签只是图 ...

  2. 小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)

    小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像) 微信小程序生成特色头像,海报等是比较常见的.下面我来介绍下实现该类小程序的过程. 首先选择前端来通过 canvas 绘制.这样比较节 ...

  3. Canvas绘制时钟

    ①首先在HTML的body标签中添加一个canvas标签,用于绘制时钟. <canvas id="myCanvas" width="600" height ...

  4. HTML5 之Canvas 绘制时钟 Demo

    <!DOCTYPE html> <html> <head> <title>Canvas 之 时钟 Demo</title> <!--简 ...

  5. html5 Canvas绘制时钟以及绘制运动的圆

    1.绘制时钟 <!-- js代码 --> <script type="text/javascript"> window.onload=function(){ ...

  6. 用canvas绘制时钟

    用canvas做时钟其实很简单,下面是我做出的效果: 是不是还挺漂亮的? 下面上代码: html <div class="whole"> <canvas id=& ...

  7. HTML5 Canvas 绘制时钟

    网上会看到很多绘制的时钟,看代码也是云里雾里,自学了下Canvas,觉得不难,就自己做了一个. 先看一下截图: 比较简陋,但是该有的都有了,样式只加了个阴影. html代码就不贴了,就一个canvas ...

  8. 使用canvas绘制时钟 (http://heeroluo.net/Article/Detail/95)

    准备工作 在HTML中指定一个区域放置时钟: <div id="clock" style="position: relative;"></di ...

  9. canvas绘制时钟及注释及save和restore的用法

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

随机推荐

  1. spring里面的ioc的理解?

    spring里面的ioc就是控制反转,其实现核心是DI(依赖注入),控制反转不向以前java代码里面,通过new关键字来实现创建对象,这样每段代码之间的耦合度就比较高,为了降低每个小模块之间的耦合度, ...

  2. esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx);

    esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx){ if (s_event_init_flag) { return ESP_ ...

  3. 3期浅析宽字节注入-----SQL注入

    通过分类的名称,你就可以找到漏洞银行的hack show视频. 吸收这个知识的几个关键的信息. 1.通过视频得到知识源.         [信息来源] 我怎么从不清楚到知道这个信息来源?这个过程没办法 ...

  4. appium+android各配置参数获取'platformName'、'platformVersion'、appActivity、deviceName、webdriver.Remote

    图中1的获取--'platformName'.'platformVersion' 点击appium右上角的运行按钮,可通过上面查看platformName 和 platformVersion 平台版本 ...

  5. Service与BoardcastReceive

    开发service需要两个步骤: 1.定义一个继承Service的子类 2.在AndroidMainfest.xml文件中配置该Service. Service与Activity都是从Context派 ...

  6. [BZOJ4204] 取球游戏(期望)

    DarkBZOJ4204 (题面来源) [题目描述] 有\(m\)个球,一开始每个球均有一个初始标号,标号范围为\(1-n\)且为整数,标号为\(i\)的球有\(a_{i}\)个,并保证\(Σa_{i ...

  7. Tomcat中查看JVM内存使用情况

    TOMCAT运行时,实时监控当前应用JVM的使用情况:可以利用Tomcat自带的应用manager查看详情. 首先,确认服务目录webapps下有manager应用 其次,需要创建角色manager和 ...

  8. Linux Intro - Remove 302 字符

    I have a file originally provided from a SQL database on a Windows platform. I transfer the file via ...

  9. greenplum表的distributed key值查看

    greenplum属于分布式的数据库,MPP+Share nothing的体系,查询的效率很快.不过,这是建立在数据分散均匀的基础上的.如果DK值设置不合理的话,完全有可能出现所有数据落在单个节点上的 ...

  10. Ubuntu系统下安装并配置hive-2.1.0

    说在前面的话 默认情况下,Hive元数据保存在内嵌的Derby数据库中,只能允许一个会话连接,只适合简单的测试.实际生产环境中不使用,为了支持多用户会话, 则需要一个独立的元数据库,使用MySQL作为 ...