以下为原始档
https://github.com/87JoJo/02---JS-and-CSS-Clock
这次的练习,是要做一个小时钟,而重点在于CSS的撰写。
如上图
transform: translate
首先我们要先做出圆心
,将.clock-face设为position:relative,然后在圆心设置position: absolute;,他就会往最近的relative当作定位点,注意当设置position: absolute;,位子的基準,是从该元素的「左上角」开始算起
,也就是说会如下图这样,因此我们光是利用left: 50%,top: 50%,并无法让圆心置中,因为还要扣掉元素本身大小的部分(他并不是位于外框交叉,而是靠外框左上),所以还要利用transform: translate(X,Y)方法
,参数分别代表位移X距离、位移Y距离,如使用%,是以元素本身大小作为计算基準,如果只写一个参数,省略的第2个参数会视为0
。
::after、::before
而这个为伪元素
,我们利用它来做圆心及针的部分,他可以有 CSS 属性,可以影响画面,但是它不是实际存在的 HTML 结构
,所以我们在console只会看到::after的元素,而我们也须加上content: '',display: block
让其佔有实际的位置,而::after是在元素的之后插入其他内容,::before反之。
.clock-face::after { position: absolute; content: ''; width: 20px; height: 20px; left: 50%; top: 50%; transform: translate(-50%, -50%); background-color: white; border-radius: 50%; display: block; }
而再来就按照设置圆心的方法,分别设置时针、分针、秒针。
在js部分,先利用选择器获取时针、分针、秒针。
const hour = document.querySelector('.hour-hand'), min = document.querySelector('.min-hand'), second = document.querySelector('.second-hand');
接着,我们设一个setClock函数来做时间及针的摆动计算操作。
先利用new Date();
获取现在时间,在利用当前时间,分别获取时getHours()
、分getMinutes()
、秒getSeconds()
,再来就要设置我们摆动的角度,让他在对应时间移动到相对的位置,由于圆圈是360度,基本上,除以60秒,1秒移动6度,除以60分,1分移动6度,除以12小时,1时移动30度,在乘上当前时分秒,即可得到对应角度,
但是,我们还需要考虑到分、时针不可能永远在整点,一定有多余的时间
,所以要加上多余的时间,对于时针,一分会移动1/2度,对于分针一秒会移动1/10度。
rotate
我们利用rotate属性来处理针的摆动,利用style,直接在时针、分针、秒针上添加transform:rotate
,利用模板字符串来将我们设置好的属性值写进去即可。
function setClock() { // 获取现在时间 const time = new Date(); // 获取时,分,秒 const nowSec = time.getSeconds(), nowMin = time.getMinutes(), nowHour = time.getHours(); // 设置移动角度 const secDeg = (360 / 60) * nowSec, // 360度/60秒 // 后面数值为多余秒数会移动的角度 1秒移动 1/10度 minDeg = (360 / 60) * nowMin + (6 / 60) * nowSec, // 后面数值为多余分钟会移动的角度,1分移动 1/2度 hourDeg = (360 / 12) * nowHour + (30 / 60) * nowMin; // 利用style直接改变定义transform并添加rotate让针翻转 hour.style.transform = `rotate(${hourDeg}deg)`; min.style.transform = `rotate(${minDeg}deg)`; second.style.transform = `rotate(${secDeg}deg)`; }
再来在最外面呼叫setClock,初始化画面,最后,设定计时器,而设定计时器有三种方法:如下
setClock(); // 三种计时方法
1.setInterval
// 间隔1秒,持续触发 setInterval(setClock, 1000);
2.setTimeout
// 等一秒后,触发一次(用来设定延迟) setTimeout(timeHandler, 1000); 在function里面添加timeHandler function timeHandler() { setClock(); // 因为只会执行一次,所以在函数里在执行一次 setTimeout(timeHandler, 1000); }
3.requestAnimationFrame
处理画面更新(与画面更新频率有关)的setTimeout,当在处理複杂动画就用requestAnimationFrame。
window.requestAnimationFrame(animationHandler, 1000); function animationHandler() { setClock(); // 因为只会执行一次,所以在函数里在执行一次 window.requestAnimationFrame(animationHandler, 1000); }