canvas个性化时钟

效果演示

在这里插入图片描述

简介

十二小时制的时钟,时刻度在圆盘上面显示,交叉线顶角为分和秒的刻度。
时分秒:最小的是秒、中等的是分、圈内的蓝点为时。
中心圆:随着秒钟缩小,数字时钟的显示。
秒钟走动的声音,每小时和每3小时的有语音提示。

代码

html

		<canvas id="can" width="860px" height="860px">
		</canvas>
		<!-- 音乐 -->
		<audio src="./audio/7987.mp3" id="aud" loop="loop" ></audio>

css

		<style type="text/css">
			body{text-align: center;background-color: black}
		</style>

js代码配合js功能函数使用

	// 获取声音
	var aud = document.getElementById('aud');
	// 点击开启声音
	document.addEventListener('click',startTime)
	function startTime(){
		aud.play();
		document.removeEventListener('click',startTime);// 开启声音后解绑事件
	}
	// 解决时间晚一秒的问题
	window.onload = function(){
		clock();
	}
	
	// 获取画布
	var can = document.getElementById('can');
	// 获取画笔
	var cx = can.getContext('2d');
	cx.translate(420,420);// 设置中心点 默认值
	
	setInterval(clock,1000);// 使用定时器调用 clock函数
	var zgongxinyuan = 246;// 控制中心圆的大小
	function clock(){
		// 清除绘画区
		cx.clearRect(-420,-420,860,860);
		
		// 获取当前时间对象
		var today = new Date();
		var hour = today.getHours();//时
		var min = today.getMinutes();//分
		var secd = today.getSeconds();//秒
		zgongxinyuan -=1;// 改变中心圆的大小
		if(secd==0){
			zgongxinyuan = 246;// 中心圆的半径
		}
		
		
		// 绘制表盘
		cx.beginPath();
		cx.arc(0,0,395,0,Math.PI*2,true);
		cx.strokeStyle = 'rgba(0,100,100,.4)';
		cx.lineWidth = '10';
		cx.stroke();
		cx.closePath();
		// 分/秒刻度
		// for(var i=0;i<4;i++){
			// 绘制分刻度 calibration 做中间转换,用来绘制刻度, 使用line函数绘制
			calibration(60,6,-388)
		// }
		// 时刻度
		// for(var i=0;i<12;i++){
			// 绘制时刻度 calibration 做中间转换,用来绘制刻度,使用 circle函数绘制 
			calibration(12,30,-396)
		// }
		
		// 时间绘制--时间处理	
		hour = hour+min/60;// 小时数里面包含的分钟的小数数
		hour>12 ?hour =hour-12:hour;// 将24小时制转为12小时制
		// 每小时提醒一次
		// console.log(secd,min)
		if(min==0 && secd==0 && hour% 3!=0 ){
			playAudio('audio/2341.mp3',1000)
		}
		// 整点提示3、6、9、12提示
		// console.log(secd,min)
		if( (hour%3==0)&& min==0 && secd==0){
			playAudio('audio/7120.mp3',2000)
		}
		  
		// 时针
		hand(hour,30,-260,12)
		// hand做 直接绘制分和时
		// 分钟
		hand(min,6,-356,8)
	
		// 秒针
		// hand(secd,6,-300,'red')
		cx.save();// 保存之前的
		cx.beginPath();
		cx.rotate(secd*6*Math.PI/180);
		// line(0,0,0,-300,'red','1','round')
		cx.closePath();
		// 中心圆:绘制的中间会慢慢变小的圆 zgongxinyuan 会变化的值在全局定义
		circle(0,zgongxinyuan,'rgba(0,100,100,.2)');
		// 秒针圆--单独绘制
		if(secd%5==0){
			//5的倍数高亮显示数字位置:就是把秒钟的半径设置和数字圆一样,微调坐标
			circle(-396,18,'#999'); 
		}else{
			// 默认大小
			circle(-384,4,'#ccc');
		}
		cx.restore();// 恢复
		
		// 小时文字填充
		cx.beginPath();// 开始路径
		cx.fillStyle = '#fff';
		cx.font = '20px 宋体'
		cx.fillText('12',-10,-390)
		cx.fillText('1',194,-336)
		cx.fillText('2',339,-190)
		cx.fillText('3',392,8)
		cx.fillText('4',338,204)
		cx.fillText('5',193,352)
		cx.fillText('6',-4,404)
		cx.fillText('7',-202,350)
		cx.fillText('8',-348,204)
		cx.fillText('9',-401,6)
		cx.fillText('10',-353,-190)
		cx.fillText('11',-208,-336)
		cx.closePath()
		
		// 绘制作者
		cx.beginPath();
		cx.strokeStyle = 'white'; 
		cx.font = '28px 宋体';
		cx.lineWidth = '1'
		cx.fillStyle = 'rgba(0,100,100,1)';
		cx.strokeText('xxxxx Made',-140,90);
		cx.fillText('xxxxx Made',-140,90)
		cx.closePath();
		
		// 绘制数字时钟
		cx.beginPath();
		// cx.strokeStyle = 'white'; 
		cx.font = '38px 宋体';
		cx.lineWidth = '1'
		var bgr = cx.createLinearGradient(-20,-100,-10,-10);//设置颜色渐变
		bgr.addColorStop(0.1,'rgba(0,100,100,1)');
		bgr.addColorStop(0.5,'rgba(0,100,100,.2)');
		bgr.addColorStop(1,'rgba(0,100,100,1)');
		cx.fillStyle = bgr;
		var numTime = `${zero(today.getHours())}:${zero(min)}:${zero(secd)}`
		cx.strokeText(numTime,-80,-20);
		cx.fillText(numTime,-80,-20)
		cx.closePath();
	}	
		

js功能函数:绘制形状比较频繁的函数封装


	// 切换语音提示
	// srcValue 文件路径
	// srcValue 播放时间
	function playAudio(srcValue,time){
		aud.src = srcValue;
		// $('#aud').attr('src',srcValue);// 新的音乐播放
		aud.play();
		setTimeout(function(){
			// 'audio/7987.mp3'为本地存储的秒钟时间声音-----可以自定义
			aud.src = 'audio/7987.mp3';// time 秒后回到原来的音乐
			aud.play();
		},time)
	}
	
	

	// 5.封装一个直线的函数
	// x1,y1开始坐标
	// x2,y2;结束坐标
	// color线条颜色
	// width线条大小
	// shape线条样式
	function line(x1,y1,x2,y2,color,width,shape){
		color = color || '#000';
		width = width || 'butt';
		shape = shape || 'butt';
		cx.save()
		cx.beginPath();// 开始路径
		cx.moveTo(x1,y1);// 起点
		cx.lineTo(x2,y2); // 终点
		cx.strokeStyle = color;// 设置颜色
		cx.lineWidth = width; // 设置大小
		cx.lineCap = shape;// 两端的状态值是  round圆角、butt、square
		cx.stroke(); // 绘制	
		cx.closePath();// 结束路径
		cx.restore();
	}
	
	// 封装一个绘制刻度的函数
	// num 刻度个数 ---数字
	// deg 表示旋转的度数
	// y1 终点坐标
	function calibration(num,deg,y1){
		for(var i=num;i>0;i--){
			cx.save();//保存
			cx.beginPath();
			cx.rotate(i*deg*Math.PI/180);
			if(num==12){
				circle(y1,18,'rgba(10,10,0,.4)',2);// 用圆绘制 小时
				// numTime(i,0, 390); // 绘制数字 bug
			}else{
				line(y1,0,0,y1,'rgba(0,100,100,.4)',2);// 用线条绘制  分钟
				// 网状绘制,由于中心点在圆盘的正中心,
				// 绘制起点在 -388 0 位置时间的,结束在 0 -388位置,没有旋转 起点应该在 45 刻度位置, 结束在 0/12 位置
				// 由于旋转了 6 度 所以起点在 46 刻度位置,结束位置在1刻度位置
				// 下次循环又旋转了 6 度 所以起点在 47 刻度位置,结束位置在2刻度位置
				// 以此类推 到循环 60 次之后,每个 分/秒 刻度上出现一个重合的点,有点像折射。
				// 就完了。
			}
			cx.closePath();// 关闭路径
			cx.restore();// 恢复
		}
	}
	
	// 绘制数字 bug
	function numTime(num,x,y){
		// 小时文字填充
		cx.save();//保存
		cx.beginPath();// 开始路径
		cx.fillStyle = '#fff';
		cx.font = '20px 宋体'
		cx.fillText(num,-10,-390)
		cx.closePath()
		cx.restore();// 恢复
	}
	
	
	// 封装时钟分钟的函数
	// time表示时间 -- 数据类型-变量
	// deg表示度数  -- 数字
	// y2 结束位置 -- 数字
	// r 半径
	function  hand(time,deg,y2,r){
		cx.save();// 保存之前的
		cx.beginPath();
		cx.rotate(time*deg*Math.PI/180);
		// line(0,0,0,y2,color,'10','round')
		if(deg==6){// 如果是分钟
			circle(y2,r,'#84AFD9',4);// 时针和分针的圆
		}else{
			circle(y2,r,'#39DEFA',4);// 时针和分针的圆
		}
		cx.closePath();
		cx.restore();// 恢复
	}
	
	// hand的扩展函数
	// y1 yz坐标位置
	// r 半径
	// color填充色
	// width画笔大小
	function circle(y1,r,color,width){
		// 秒针圆
		cx.beginPath();// 开始路径
		cx.strokeStyle = 'rgba(10,100,100,.4)';
		cx.lineWidth = '4';
		cx.arc(0,y1,r,0,Math.PI*2,true);// 中心点
		cx.fillStyle = color;
		cx.fill();
		cx.stroke(); // 绘制
		cx.closePath();// 结束路径
	}
	// 去0补位
	function zero(num){
		return num<10?	'0'+num : num;
	}

音频文件路径设置需要自己引入文件

audio标签默认是秒钟的声音,可以自己设置。
每小时语音提示代码修改路径和提示时间

// 每小时提醒一次
	console.log(secd,min)
		if(min==0 && secd==0 && hour% 3!=0 ){
			playAudio('audio/2341.mp3',1000)
		}
		// 整点提示3、6、9、12提示
		// console.log(secd,min)
		if( (hour%3==0)&& min==0 && secd==0){
			playAudio('audio/7120.mp3',2000)
		}

音频开启

需要点击一下任意位置开始或者等小时提示的信息结束后,才能播放,试了好多种方式开启音频,最后点击一下任意位置开启是最稳定的,有更好的方式希望大家多分享分享

// 点击开启声音
	document.addEventListener('click',startTime)
	function startTime(){
		aud.play();
		document.removeEventListener('click',startTime);// 开启声音后解绑事件
	}

canvas使用分享

刚使用canvas的时候,对于我来说找坐标点有点晕,尤其是使用 translate() 重新设置中心点之后更晕了。
找坐标
通过 offsetX,offsetY获取鼠标在元素(canvas)的位置。将值直接输出到页面中就能得到一个大致的值,如果从新设置了中心点,需要把设置中心点的位置也算进去。

	// 鼠标在画布上的位置
	var x = document.getElementById('x');
	var y = document.getElementById('y');
	document.onmousemove = function(e){
		x.innerHTML ='x坐标:'+ e.offsetX;
		y.innerHTML ='y坐标:'+ e.offsetY;
	}
		    
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页