JavaScript罗盘实现

JavaScript罗盘实现,第1张

因为罗盘是准备绘制在一个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-{0}{0%{transform:rotateZ({1}deg);}{2}%{transform:rotateZ({3}deg);}100%{transform:rotateZ({3}deg);}}".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;
		}
	}

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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1322739.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存