自定义H5元素时钟完美版
<style>.papa > p { margin: 10px 0; }
.mama { margin-left: 40px; position: relative; }
.hCode, .hLineNum { padding: 10px; width: calc(100% - 40px); font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; background: #f9f9f9; box-sizing: border-box; overflow-x: auto; tab-size: 3; position: absolute; }
.hCode { left: 40px; margin-left: -40px; padding-left: 45px; }
.hLineNum { width: 40px; background: #ccc; border-right: 1px solid #ccc; text-align: right; pointer-events: none; }
.stage { display: grid; place-items: center; }
.hidden { display: none; }
</style>
<div class="papa">
<p>以下代码使用自定义元素制作时钟,时钟的钟点数字使用CSS三角函数布局、时间刻度使用transform布局:</p>
<div class="mama">
<pre class="hCode"><style>
my-clock {
width: 200px;
height: 200px;
border: 10px solid olive;
background: lightgray;
border-radius: 50%;
box-shadow: 0 0 8px black;
display: grid;
place-items: center;
position: relative;
--ww: 200px;
--num_ww: 26px;
--rr: calc((var(--ww) - var(--num_ww)) / 2);
}
my-clock::before, my-clock::after { position: absolute; content: ''; }
my-clock::before {
width: 16px;
height: 16px;
border-radius: 50%;
background: olive;
}
my-clock::after { content: 'HUA CHAO'; top: 65%; color: rgba(0,0,0,.5); }
hand-pointer, kedu-num, kedu-sec { position: absolute; display: block; }
kedu-number {
position: absolute;
width: var(--num_ww);
height: var(--num_ww);
font: normal 20px / var(--num_ww) Arial, sans-serif;
text-shadow: 1px 1px 2px black;
text-align: center;
color: snow;
left: calc(var(--rr) + var(--rr) * var(--cos));
top: calc(var(--rr) + var(--rr) * var(--sin));
--cos: cos(var(--deg));
--sin: sin(var(--deg));
}
kedu-sec { width: 8px; height: 4px; background: olive; }
hand-pointer {
transform-origin: 50% 100%;
background: linear-gradient(snow,olive);
width: var(--hand_ww);
height: calc(var(--ww) / 2 - var(--hand_hh));
top: var(--hand_hh);
animation: rot var(--duration) var(--delay) infinite linear;
}
@keyframes rot { to {transform: rotate(1turn); } }
</style>
<my-clock id="clock"></my-clock>
<script>
let kedu_ar = , hand_ar = [,,];
let now = new Date();
let secs = -1 * now.getSeconds(), mins = -60 * now.getMinutes(), hrs = -3600 * (now.getHours() % 12) + mins;
let tt_ar = ;
kedu_ar.forEach((item,key) => {
let ele = document.createElement('kedu-number');
ele.innerText = key > 0 ? key : 12;
ele.style.setProperty('--deg', kedu_ar + 'deg');
clock.appendChild(ele);
});
Array.from({length: 60}).forEach((item,key) => {
let ele = document.createElement('kedu-sec');
ele.style.transform = `rotate(${6 * key}deg) translate(${clock.offsetWidth / 2 - 10}px)`;
if(key % 5 === 0) ele.style.background = 'linear-gradient(to right,snow 50%,olive 0)';
clock.appendChild(ele);
});
hand_ar.forEach((item,key) => {
item.push(tt_ar);
let properties = [['--hand_ww','px'],['--hand_hh','px'],['--duration','s'],['--delay','s']];
let ele = document.createElement('hand-pointer');
ele.style.zIndex = key + 1;
properties.forEach((item1,key1) => ele.style.setProperty(properties, hand_ar + properties));
clock.appendChild(ele);
});
</script></pre>
<pre class="hLineNum"></pre>
</div>
<p><button class="btnok" type="button" value="运行代码">运行代码</button></p>
<div class="stage"></div>
</div>
<script>
let btns = document.querySelectorAll('.btnok'),
stages = document.querySelectorAll('.stage'),
hCodes = document.querySelectorAll('.hCode'),
hLineNums = document.querySelectorAll('.hLineNum'),
mamas = document.querySelectorAll('.mama');
hCodes.forEach((item,key) => {
let lines = hCodes.innerText.trim().split('\n').length;
let str = '';
for(let i = 0; i < lines; i ++) {
str += i + 1 + '\n';
}
hLineNums.innerText = str;
mamas.style.cssText += `height: ${hCodes.offsetHeight + 20}px`;
if(!btns) return;
btns.onclick = () => {
let val = btns.value;
val === '运行代码' ? codeRun(hCodes.innerText, stages) : codeRun('',stages);
btns.value = btns.innerText = val === '运行代码' ? '关闭运行' : '运行代码';
};
});
let codeRun = (str,ele) => {
let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
let js_str, html_str;
if(str.match(reg) !== null) {
js_str = str.match(reg);
html_str = str.replace(js_str, '').trim();
js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
} else {
js_str = '';
html_str = str.trim();
}
ele.innerHTML = html_str;
let myfunc = new Function(js_str);
myfunc();
};
</script>
时钟的实现,全部使用自定义元素。
原先的版本,由 CSS + HTML 写好所有的一切,这里因为引入秒钟刻度,写 60 个刻度的CSS层叠样式和HTML元素就太繁琐了,所以借助JS来完成大部分工作。JS大约做如下界面绘制工作:
其一:57-62行,绘制与布局数字刻度;
其二:63-68行,绘制与布局秒钟刻度;
其三:69-76行:绘制与布局时分秒指针。
每一种绘制与布局,都依赖于CSS变量和一些预设数据,都是精心设计的,并尽可能地优化了算法。
指针扣与时钟logo,用主元素的两个伪元素完成。 26行代码多余,可以删掉 35和36行,单独计算余弦与正弦函数,其实也可以整合到33和34行,但一些有语法检测的前端代码编辑器会认为calc算式非法,所以单独列出来。 有花潮标识的时钟,专属logo。所有时钟中论颜值这个当属第一{:4_173:} 南无月 发表于 2023-5-29 20:18
有花潮标识的时钟,专属logo。所有时钟中论颜值这个当属第一
过得去 醉美水芙蓉 发表于 2023-5-29 20:52
欣赏老师完美时钟!
晚上嚎 最完美的花潮专用是时钟,谢谢黑黑{:4_199:} 红影 发表于 2023-5-29 21:50
最完美的花潮专用是时钟,谢谢黑黑
{:4_190:} 黑黑老师厉害。赞!{:4_190:} 焱鑫磊 发表于 2023-6-4 16:54
黑黑老师厉害。赞!
晚上嚎 马黑黑 发表于 2023-5-29 19:52
26行代码多余,可以删掉
黑黑,昨天晚上做了这个时钟效果,发现26行不能删除的 小辣椒 发表于 2023-7-5 13:33
黑黑,昨天晚上做了这个时钟效果,发现26行不能删除的
那就不删 马黑黑 发表于 2023-7-5 19:07
那就不删
没有删,昨天晚上捣鼓了一个 小辣椒 发表于 2023-7-5 19:16
没有删,昨天晚上捣鼓了一个
看到的,漂酿的说 马黑黑 发表于 2023-7-5 21:07
看到的,漂酿的说
是套用代码的,黑黑可惜我加小珠珠播放器没有成功,不会加{:4_198:} 小辣椒 发表于 2023-7-7 17:04
是套用代码的,黑黑可惜我加小珠珠播放器没有成功,不会加
多种效果加在一起,需要明白各种效果的原理,同时需要避免名称、变量的重复。 马黑黑 发表于 2023-7-7 18:12
多种效果加在一起,需要明白各种效果的原理,同时需要避免名称、变量的重复。
这个就是我的短板 小辣椒 发表于 2023-7-7 22:52
这个就是我的短板
这是不会具体语言的短板。做帖子,要有自由能力,要求对 HTML、CSS、JS有一定的基础
页:
[1]
2