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);// 开始时间
	var zgongxinyuan = 246;// 控制中心圆的大小
	function clock(){
     
		zgongxinyuan -=1;
		// 获取当前时间对象
		var today = new Date();
		var hour = today.getHours();//时
		var min = today.getMinutes();//分
		var secd = today.getSeconds();//秒
		if(secd==0){
     
			zgongxinyuan = 246;// 中心圆的半径
		}
		
		// 清除绘画区
		cx.clearRect(-420,-420,860,860);
		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<60;i++){
     
			calibration(60,6,-388);// 网格线
		}
		// 时刻度
		for(var i=0;i<12;i++){
     
			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(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();
		// 中心圆
		circle(0,zgongxinyuan,'rgba(0,100,100,.2)');
		// 秒针圆
		if(secd%5==0){
     
			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.strokeStyle = 'seagreen';
					cx.rotate(i*deg*Math.PI/180);
					if(num==12){
     
						circle(y1,18,'rgba(10,10,0,.4)',2);
					}else{
     
						line(y1,0,0,y1,'rgba(0,100,100,.4)',1);
					}
					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();// 恢复
			}
			// 圆形绘制函数
			// 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;
	}
		    

你可能感兴趣的:(原生js,个性化时钟,audio,canvas,js)