JavaScript罗盘实现

Posted 阿飞超努力

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript罗盘实现相关的知识,希望对你有一定的参考价值。

  • 因为罗盘是准备绘制在一个dom之中,所以先扩展一个方法,百度一下,罗盘的翻译是compass
document.getElementById("box").compass();
  • 然后用上这个写法来达到预设参数的效果,当然很多参数只是先设计了,暂时没用到
Element.prototype.compass=
function(type='compass-0',method='dom',speed=25,bcolor='white',mcolor='rgba(255,255,255,0.5)',fontSize=14=)
  • 接着绘制对应的dom结合css把罗盘部分完成
.compass-year
	position: absolute;
	width: 16%;
	height: 16%;
	border-radius: 50%;
	z-index: 6;
	display: flex;
	justify-content: center;
	align-items: center;

/*略*/
.compass-second
	position: absolute;
	width: 96%;
	height: 96%;
	border-radius: 50%;
	z-index: 1;
	display: flex;
	justify-content: center;
	align-items: center;

	var $that = this;
	//先添加类
	$that.classList.add('compass',type)
	$that.style.fontSize = fontSize+'px';
	//先添加6个罗盘
	var $year = document.createElement('div');
	$year.classList.add('compass-year');
	var $month = document.createElement('div');
	$month.classList.add('compass-month');
	var $day = document.createElement('div');
	$day.classList.add('compass-day');
	var $hour = document.createElement('div');
	$hour.classList.add('compass-hour');
	var $minute = document.createElement('div');
	$minute.classList.add('compass-minute');
	var $second = document.createElement('div')
	$second.classList.add('compass-second');
	var $titlemask = document.createElement('div');
	$titlemask.classList.add('titlemask');
	$that.appendChild($year);
	$that.appendChild($month);
	$that.appendChild($day);
	$that.appendChild($hour);
	$that.appendChild($minute);
	$that.appendChild($second);
	$that.appendChild($titlemask);
  • 再把里面的刻度全部绘制进去,配合transform:rotate()这个样式挨个旋转对应的角度,比如秒盘有60个刻度平均分为6deg一个刻度
.seconditem
	width: 100%;
	height: 20px;
	position: absolute;
	display: flex;
	justify-content: flex-end;
	align-items: center;

	var seconddegree = 360/60;
	for (var i=0;i<60;i++) 
		var str = i.toString().length==1?'0'+i:i+'';
		var $seconditem = document.createElement('div');
		$seconditem.classList.add('seconditem');
		$seconditem.innerText=str;
		$seconditem.style.transform = 'rotate('+(seconddegree*i)+'deg)';
		$second.appendChild($seconditem);
	
	//其他刻度同理
  • 继续绘制指针,其实就是标记一下焦点告诉看客往哪看才是罗盘的正确时间,其中要理解box-shadow的用处,就比如我每个图层都浮动起来之后有个层级的关系z-index,我们要将展示的时刻正常显示,其他区域虚化或者变透明,那么我们就把指针的层级调到表盘的上方,然后用box-shadow直接把阴影填满直接覆盖整个容器,并且颜色用rgba(255,255,255,0.7)留点雾蒙蒙的感觉,这样指针本身的颜色可以设置,除指针以外的表盘也能被虚化和透明了
  • 表盘绘制完了之后就着手让时钟动起来,先确定时间,确定时间之后就可以每一秒钟执行一次动作了
	var start = new Date().getTime();
	var tick = parseInt(start.toString().substr(10,3));
	var wait = 1000-tick;
	setTimeout(function()
		setInterval(function()
			cal_pos()
		,1000)
	,wait);
  • 关于动画的实现,一开始是直接通过动态添加transform:rotate()到表盘本身来旋转出效果,只要设置表盘属性transition的动态效果就很简单,但是实际上这样设置有问题,因为我们要记录旋转的度数并且会一直的累计直到超出内存,而且这种方式也不能在59的到00的时候通过重置度数的记录达到顺滑的动画效果,所以放弃了这个方法,转而找到了animation+@keyframes的动画帧的方式实现,这样我就需要通过js去生成动态的样式表
	//添加一个动态的style标签
	var $head = document.head||document.getElementsByTagName('head')[0];
	var $style = document.createElement('style');
	$style.type='text/css';
	$head.appendChild($style);
	var style = $style.sheet||$style.styleSheet[0];
	
	//然后在每个表盘生成刻度的时候同时写入关键帧的css样式,以秒盘做例子
	style.insertRule(
			"@keyframes second-00%transform:rotateZ(1deg);2%transform:rotateZ(3deg);100%transform:rotateZ(3deg);".format(i,-((i-1)*seconddegree),speed,-(i*seconddegree))
		)
		
	//其中format的方法是拓展的如下
	String.prototype.format = function (args) 
    if (arguments.length > 0) 
        var result = this;
        if (arguments.length == 1 && typeof (args) == "object") 
            for (var key in args) 
                var reg = new RegExp("(" + key + ")", "g");
                result = result.replace(reg, args[key]);
            
         else 
            for (var i = 0; i < arguments.length; i++) 
                if (arguments[i] == undefined) 
                    return "";
                 else 
                    var reg = new RegExp("([" + i + "])", "g");
                    result = result.replace(reg, arguments[i]);
                
            
        
        return result;
     else 
        return this;
    

关键帧全部绘制完成之后,要注意animation里面的forwards属性,要让动画执行之后保持最后一帧的样式效果,最后就是实现我所有表盘的动画cal_pos()这个方法了

	//计算罗盘位置
	cal_pos();
	var flag = true;
	function cal_pos()
		//计算
		var now = new Date();
		var year = now.getUTCFullYear();
		var month = now.getMonth()+1;
		var day = now.getDate();
		var hour = now.getHours();
		var minute = now.getMinutes();
		var second = now.getSeconds();
		//校对
		if(flag)
			flag = false;
			$second.style.animation = "second-"+second+" 1s";
			$minute.style.animation = "minute-"+minute+" 1s";
			$hour.style.animation = "hour-"+hour+" 1s";
			$day.style.animation = "day-"+(day-1)+" 1s";
			$month.style.animation = "month-"+month+" 1s";
			$year.innerText = year;
		
		//秒
		$second.style.animation = "second-"+second+" 1s";
		//分	
		if(second==0)
			$minute.style.animation = "minute-"+minute+" 1s";
		
		//时
		if(minute==0)
			$hour.style.animation = "hour-"+hour+" 1s";
		
		//天
		if(hour==0)
			$day.style.animation = "day-"+(day-1)+" 1s";
		
		//月
		if(day==0)
			$month.style.animation = "month-"+month+" 1s";
		
		//年
		if(month==1&&day==0&&hour==0&&minute==0&&second==0)
			$year.innerText = year;
		
	

至此效果完成,展示界面点这里进入

以上是关于JavaScript罗盘实现的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript罗盘实现

微信小程序入门-指南针

图标插件--jqplot实现柱状图及饼图,表盘图演示样例

JavaScript Javascript十进制到谷歌地图的度数

记录--ThreeJs手搓一个罗盘特效

在 JavaScript 中旋转人脸 (Node.js 10)