各位慕课网的小伙伴们大家好,今天为大家带来一款由HTMLCSSJS编写的钟表。主要面向前端初学者。
话不多说,惯例,先上最终效果和html代码方便讲解
<body>
<div class="mainclock" id="mainclock">//主容器,是一个圆形
<div class="yuandian" id="yuandian">//中心的黑色原点
</div>
<div class="kedupan">//刻度盘容器,单纯的包裹元素,没有样式
<div class="kedu">//刻度模版容器
<div class="kedu_i"></div>//刻度,包含一个黑色矩形背景图片,作为刻度
</div>
</div>
<div class="numpan">//数字包裹容器,也是没有样式的
<div class="num">//数字模版容器
<div class="num_i"></div>//数字,将来会在其内加入一个数字
</div>
</div>
<div class="zhizhen" id="shizhen">//时针容器
<div id="shizhen1"></div>//时针的屁股
<div id="shizhen2"></div>//时针的头
</div>
<div class="zhizhen" id="fenzhen">//分针
<div id="fenzhen1"></div>
<div id="fenzhen2"></div>
</div>
<div class="zhizhen" id="miaozhen">//秒针
<div id="miaozhen1"></div>
<div id="miaozhen2"></div>
</div>
</div>
</body>
各元素容器样式介绍/
1 div.mainclock
.mainclock{
width:400px;
height:400px;
border:1px solid #000;
position:absolute;
left:1300px;
margin-left:-200px;
top:100px;
border-radius:200px;
background:#fff;
}
主要是一个border-radius的应用,让圆角半径=div宽高的一半,div就会变成一个圆
2 div.yuandian
.mainclock .yuandian{
width:20px;
height:20px;
background:#000;
border-radius:10px;
position:absolute;
top:50%;
left:50%;
margin:-10px 0 0 -10px;
z-index:999;
}
同理,设置border-radius让div变成圆形;
设置绝对定位,top、left为50%,margin上和左分别为宽高一半的负值,可以水平垂直居中该div;
设置一个高的z-index,因为该原点以后将覆盖3个指针,你可以看看你家的表,是不是这样。
3 div.kedu div.kedu_i
.mainclock .num,
.mainclock .kedu,
.mainclock .zhizhen{
width:2px;
height:10px;
position:absolute;
top:200px;
left:200px;
margin-left:-1px;
margin-top:-5px;
transform:rotate(0deg);
}
.mainclock .kedu .kedu_i{
width:10px;
height:12px;
position:absolute;
left:1px;
bottom:185px;
margin-left:-5px;
background:url(../img/kedu.jpg) no-repeat scroll -40px -10px;
}
单纯的看div.kedu的样式,其实和原点的样式是一致的,只不过.kedu是一个2×10的透明矩形,通过绝对定位让其相对于父元素div.mainclock水平垂直居中。给一个旋转角度0度。 div.kedu的作用是个div.kedu_i提供定位;
div.kedu同样是一个透明矩形,绝对定位于父元素div.kedu的头顶185px的位置,并相对父元素水平居中,其内是一个背景图片,一种是大刻度5的倍数,一种小刻度是其余刻度,这里用到spirit图,改变定位就可以改变显示不同的图片。
4 div.num div.num_i
.mainclock .num .num_i{
width:40px;
height:35px;
position:absolute;
left:1px;
bottom:145px;
margin-left:-20px;
text-align:center;
font-size:30px;
}
div.num和上面的div.kedu是一个样式,因为它仅仅是为div.num_i提供一个包裹和定位作用;
div.num_i和前面的div.kedu_i也是差不多的,不同在于bottom值变下了,相对位置变的更接近中心。其内,将来会用JS写入数字。
5 div.zhizhen div#shizhen1 div#shizhen2
#shizhen1{
width:10px;
height:60px;
background:#096;
position:absolute;
top:5px;
left:1px;
margin-left:-5px;
margin-top:-40px;
z-index:10;
border-radius:5px;
}
#shizhen2{
position:absolute;
width:0;
height:0;
border-left:5px solid transparent;
border-right:5px solid transparent;
border-bottom:50px solid #096;
bottom:45px;
left:-4px;
z-index:10;
}
div.zhizhen和前面的div.kedu一样,提供子元素的包裹和定位作用;
时针屁股div#shizhen1,绝对定位让其相对原点位置水平居中,垂直位置,通过控制margin-top调整,给一个z-index=10,为了和分针秒针区分位置。给一个圆角,让其更像屁股;
时针头div#shizhen2,绝对定位让其相对原点位置水平居中,垂直位置,通过控制margin-top调整,注意这里的头是一个三角形,关于如何制作三角形,这里就不赘述了,百度轻易就可获得。
6 div#fenzhen和miaozhen这里也不赘述了,和时针差不多,只是大小、位置和z-index有区别。
JS代码部分/
1 几个要用到的通用函数定义
function g(id){//通用获取已知id或classname的元素
if(id.substr(0,1)=='.'){
return document.getElementsByClassName(id.substr(1));
}
return document.getElementById(id);
}
function g2(div,classname){//获取某个已知id的元素下,某个classname的元素
return g(div).getElementsByClassName(classname.substr(1));
}
g()等价于jq中的$(id)和$(classname);
g2()等价于jq中的$('id classname');
function addelem(div,classname,k,index){//获取模版(div下的classname),复制k个模版,并将第一个index替换为0-k的顺序数
var out_turn=[];
for(var i=0;i<k;i++){
var _html=g2(div,classname)[0].innerHTML.replace(index,i)
.replace(/^\s*/,'')
.replace(/\s*$/,'');;//去除模版元素前后的空格
out_turn.push(_html);
}
g2(div,classname)[0].innerHTML=out_turn.join('');
}
2 60个刻度以及12个数字的生成
addelem('mainclock','.kedupan',60,'{{}}');//获取#mainclock下.kedupan的内容为模版,复制60个,并替换{{}}为顺序值,这里没有需要替换的,因为正则{{}}实际上不会替换任何元素
addelem('mainclock','.numpan',12,'{{}}');//同理,生成12个数字元素,但此时里面还是没数字的。
3 周向排列刻度盘
function circle(id,classname,n){//使id元素下所有classname元素成圆周向排列
var html=[];
html=g2(id,classname);
for(var i=0;i<html.length;i++){
var _deg=+360/n*i;
var _tran='rotate('+_deg+'deg)';
html[i].style.transform=_tran;//遍历60个刻度容器,每个依次选择6°
if(i%5===0){//如果是5的倍数,说明是大刻度,改变背景,显示大刻度
html[i].getElementsByClassName('kedu_i')[0].style.background='url(img/kedu.jpg) no-repeat scroll -7px -6px';
}
}
}
circle('mainclock','.kedu',60);
这样就把addelem加载的60个刻度,呈周向排列了,并且5的备注替换了大刻度。
4 周向排列数字盘,并写入数字
function circle2(id,classname,n){//使id元素下所有classname元素成圆周向排列
var html=[];
html=g2(id,classname);
for(var i=0;i<html.length;i++){
var _deg=+360/n*i;
var _tran='rotate('+_deg+'deg)';
html[i].style.transform=_tran;//让每个数字多选择30°
html[i].getElementsByClassName('num_i')[0].innerHTML=1+(11+i)%12;//为每个数字盘里填入数字,注意这个表达式的写法,因为i=0时数字填12,i=1时数字填1。
if(i>3&&i<9){//位于表盘下半部的数字,倒过来了,我们再把它旋转180,让数字正过来。
html[i].getElementsByClassName('num_i')[0].style.transform='rotate(180deg)';
}
}
}
circle2('mainclock','.num',12);
这样就把addelem加载的12个数字,呈周向排列,并填入了数字。
5 最后我们让指针动起来
function clock(){
var myDate=new Date();//获取当前日期对象
var hour=myDate.getHours();//获取小时
var minute=myDate.getMinutes();//获取分钟
var sec=myDate.getSeconds();//获取秒针
var tran_miao='rotate('+6*sec+'deg)';//计算秒针旋转角度和transform样式
var tran_fen=6*minute+0.1*sec;//计算分针旋转角度
tran_fen='rotate('+tran_fen+'deg)';//定义分针的transform样式
var tran_hour=30*hour+0.5*minute;//计算时针旋转角度
tran_hour='rotate('+tran_hour+'deg)';//定义时针的transform样式
g('miaozhen').style.transform=tran_miao;//旋转秒针
g('fenzhen').style.transform=tran_fen;//旋转分针
g('shizhen').style.transform=tran_hour;//旋转时针
}
clock();//页面加载完成后立即执行一次指针旋转函数
setInterval("clock();",1000);//每1S循环执行一次指针旋转
整个钟表到这里就完成,小伙伴们,好不好玩!
热门评论
kedupan那个样式没写
大佬6666666666
刻度里的背景图呢??????