马黑黑 发表于 2023-5-29 19:40

自定义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">&lt;style&gt;
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); } }
&lt;/style&gt;

&lt;my-clock id="clock"&gt;&lt;/my-clock&gt;

&lt;script&gt;
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) =&gt; {
        let ele = document.createElement('kedu-number');
        ele.innerText = key &gt; 0 ? key : 12;
        ele.style.setProperty('--deg', kedu_ar + 'deg');
        clock.appendChild(ele);
});
Array.from({length: 60}).forEach((item,key) =&gt; {
        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) =&gt; {
        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) =&gt; ele.style.setProperty(properties, hand_ar + properties));
        clock.appendChild(ele);
});
&lt;/script&gt;</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>

马黑黑 发表于 2023-5-29 19:48

时钟的实现,全部使用自定义元素。

原先的版本,由 CSS + HTML 写好所有的一切,这里因为引入秒钟刻度,写 60 个刻度的CSS层叠样式和HTML元素就太繁琐了,所以借助JS来完成大部分工作。JS大约做如下界面绘制工作:

其一:57-62行,绘制与布局数字刻度;

其二:63-68行,绘制与布局秒钟刻度;

其三:69-76行:绘制与布局时分秒指针。

每一种绘制与布局,都依赖于CSS变量和一些预设数据,都是精心设计的,并尽可能地优化了算法。

指针扣与时钟logo,用主元素的两个伪元素完成。

马黑黑 发表于 2023-5-29 19:52

26行代码多余,可以删掉

马黑黑 发表于 2023-5-29 19:56

35和36行,单独计算余弦与正弦函数,其实也可以整合到33和34行,但一些有语法检测的前端代码编辑器会认为calc算式非法,所以单独列出来。

南无月 发表于 2023-5-29 20:18

有花潮标识的时钟,专属logo。所有时钟中论颜值这个当属第一{:4_173:}

马黑黑 发表于 2023-5-29 20:21

南无月 发表于 2023-5-29 20:18
有花潮标识的时钟,专属logo。所有时钟中论颜值这个当属第一

过得去

醉美水芙蓉 发表于 2023-5-29 20:52

马黑黑 发表于 2023-5-29 21:04

醉美水芙蓉 发表于 2023-5-29 20:52
欣赏老师完美时钟!

晚上嚎

红影 发表于 2023-5-29 21:50

最完美的花潮专用是时钟,谢谢黑黑{:4_199:}

马黑黑 发表于 2023-5-29 22:36

红影 发表于 2023-5-29 21:50
最完美的花潮专用是时钟,谢谢黑黑

{:4_190:}

焱鑫磊 发表于 2023-6-4 16:54

黑黑老师厉害。赞!{:4_190:}

马黑黑 发表于 2023-6-4 19:40

焱鑫磊 发表于 2023-6-4 16:54
黑黑老师厉害。赞!

晚上嚎

小辣椒 发表于 2023-7-5 13:33

马黑黑 发表于 2023-5-29 19:52
26行代码多余,可以删掉

黑黑,昨天晚上做了这个时钟效果,发现26行不能删除的

马黑黑 发表于 2023-7-5 19:07

小辣椒 发表于 2023-7-5 13:33
黑黑,昨天晚上做了这个时钟效果,发现26行不能删除的

那就不删

小辣椒 发表于 2023-7-5 19:16

马黑黑 发表于 2023-7-5 19:07
那就不删

没有删,昨天晚上捣鼓了一个

马黑黑 发表于 2023-7-5 21:07

小辣椒 发表于 2023-7-5 19:16
没有删,昨天晚上捣鼓了一个

看到的,漂酿的说

小辣椒 发表于 2023-7-7 17:04

马黑黑 发表于 2023-7-5 21:07
看到的,漂酿的说

是套用代码的,黑黑可惜我加小珠珠播放器没有成功,不会加{:4_198:}

马黑黑 发表于 2023-7-7 18:12

小辣椒 发表于 2023-7-7 17:04
是套用代码的,黑黑可惜我加小珠珠播放器没有成功,不会加

多种效果加在一起,需要明白各种效果的原理,同时需要避免名称、变量的重复。

小辣椒 发表于 2023-7-7 22:52

马黑黑 发表于 2023-7-7 18:12
多种效果加在一起,需要明白各种效果的原理,同时需要避免名称、变量的重复。

这个就是我的短板

马黑黑 发表于 2023-7-7 23:03

小辣椒 发表于 2023-7-7 22:52
这个就是我的短板

这是不会具体语言的短板。做帖子,要有自由能力,要求对 HTML、CSS、JS有一定的基础
页: [1] 2
查看完整版本: 自定义H5元素时钟完美版