一款好看的HTML钟表单页,代码如下:

<html>
    <head>
        <meta charset="utf-8">
        <style>
            * {
                border: 0;
                box-sizing: border-box;
                margin: 0;
                padding: 0;
            }

            :root {
                --hue: 223;
                --bg: hsl(var(--hue),10%,90%);
                --fg: hsl(var(--hue),10%,10%);
                font-size: calc(16px + (24 - 16) * (100vw - 320px) / (1280 - 320));
            }

            body, button {
                /*color: #fff;*/
                color: #000;
                font: 1em/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            }

            body {
                /*background-color: #1F1F1F;*/
                background-color: #FFFFFF;
                height: 100vh;
                display: grid;
                place-items: center;
            }

            .progress-clock {
                display: grid;
                justify-content: center;
                align-content: center;
                position: relative;
                text-align: center;
                width: 16em;
                height: 16em;
            }

            .progress-clock__time-date, .progress-clock__time-digit, .progress-clock__time-colon, .progress-clock__time-ampm {
                transition: color 0.2s linear;
                -webkit-user-select: none;
                -moz-user-select: none;
                user-select: none;
            }

            .progress-clock__time-date, .progress-clock__time-digit {
                background: transparent;
            }

            .progress-clock__time-date, .progress-clock__time-ampm {
                grid-column: 1 / 6;
            }

            .progress-clock__time-date {
                font-size: 0.75em;
                line-height: 1.33;
            }

            .progress-clock__time-digit, .progress-clock__time-colon {
                font-size: 2em;
                font-weight: 400;
                grid-row: 2;
            }

            .progress-clock__time-colon {
                line-height: 1.275;
            }

            .progress-clock__time-ampm {
                cursor: default;
                grid-row: 3;
            }

            .progress-clock__rings {
                display: block;
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                z-index: -1;
            }

            .progress-clock__ring {
                opacity: 0.1;
            }

            .progress-clock__ring-fill {
                transition: opacity 0s 0.3s linear, stroke-dashoffset 0.3s ease-in-out;
            }

            .progress-clock__ring-fill--360 {
                opacity: 0;
                stroke-dashoffset: 0;
                transition-duration: 0.3s;
            }

            [data-group]:focus {
                outline: transparent;
            }

            [data-units] {
                transition: opacity 0.2s linear;
            }

            [data-group="d"]:focus, [data-group="d"]:hover {
                color: hsl(333,90%,55%);
            }

            [data-group="h"]:focus, [data-group="h"]:hover {
                color: hsl(33,90%,55%);
            }

            [data-group="m"]:focus, [data-group="m"]:hover {
                color: hsl(213,90%,55%);
            }

            [data-group="s"]:focus, [data-group="s"]:hover {
                color: hsl(273,90%,55%);
            }

            [data-group]:focus ~ .progress-clock__rings [data-units], [data-group]:hover ~ .progress-clock__rings [data-units] {
                opacity: 0.2;
            }

            [data-group="d"]:focus ~ .progress-clock__rings [data-units="d"], [data-group="d"]:hover ~ .progress-clock__rings [data-units="d"], [data-group="h"]:focus ~ .progress-clock__rings [data-units="h"], [data-group="h"]:hover ~ .progress-clock__rings [data-units="h"], [data-group="m"]:focus ~ .progress-clock__rings [data-units="m"], [data-group="m"]:hover ~ .progress-clock__rings [data-units="m"], [data-group="s"]:focus ~ .progress-clock__rings [data-units="s"], [data-group="s"]:hover ~ .progress-clock__rings [data-units="s"] {
                opacity: 1;
            }

            /* Dark theme */
            @media (prefers-color-scheme: dark) {
                :root {
                    --bg: hsl(var(--hue),10%,10%);
                    --fg: hsl(var(--hue),10%,90%);
                }

                .progress-clock__ring {
                    opacity: 0.2;
                }
            }
        </style>
    </head>
    <body>
        <div id="clock" class="progress-clock">
            <button class="progress-clock__time-date" data-group="d" type="button">
                <small data-unit="w">星期日</small>
                <br>
                <span data-unit="y">2020</span><span>年</span>
                <span data-unit="mo">一月</span>
                <span data-unit="d">1</span><span>日</span>
            </button>
            <button class="progress-clock__time-digit" data-unit="h" data-group="h" type="button">12</button>
            <span class="progress-clock__time-colon">:</span>
            <button class="progress-clock__time-digit" data-unit="m" data-group="m" type="button">00</button>
            <span class="progress-clock__time-colon">:</span>
            <button class="progress-clock__time-digit" data-unit="s" data-group="s" type="button">00</button>
            <span class="progress-clock__time-ampm" data-unit="ap">AM</span>
            <svg class="progress-clock__rings"   viewBox="0 0 256 256">
                <defs>
                    <linearGradient id="pc-red" x1="1" y1="0.5" x2="0" y2="0.5">
                        <stop offset="0%" stop-color="hsl(343,90%,55%)"/>
                        <stop offset="100%" stop-color="hsl(323,90%,55%)"/>
                    </linearGradient>
                    <linearGradient id="pc-yellow" x1="1" y1="0.5" x2="0" y2="0.5">
                        <stop offset="0%" stop-color="hsl(43,90%,55%)"/>
                        <stop offset="100%" stop-color="hsl(23,90%,55%)"/>
                    </linearGradient>
                    <linearGradient id="pc-blue" x1="1" y1="0.5" x2="0" y2="0.5">
                        <stop offset="0%" stop-color="hsl(223,90%,55%)"/>
                        <stop offset="100%" stop-color="hsl(203,90%,55%)"/>
                    </linearGradient>
                    <linearGradient id="pc-purple" x1="1" y1="0.5" x2="0" y2="0.5">
                        <stop offset="0%" stop-color="hsl(283,90%,55%)"/>
                        <stop offset="100%" stop-color="hsl(263,90%,55%)"/>
                    </linearGradient>
                </defs>
                <!-- Days of Month -->
                <g data-units="d">
                    <circle class="progress-clock__ring" cx="128" cy="128" r="74" fill="none" opacity="0.1" stroke="url(#pc-red)" stroke-/>
                    <circle class="progress-clock__ring-fill" data-ring="mo" cx="128" cy="128" r="74" fill="none" stroke="url(#pc-red)" stroke- stroke-dasharray="465 465" stroke-dashoffset="465" stroke-linecap="round" transform="rotate(-90,128,128)"/>
                </g>
                <!-- Hours of Day -->
                <g data-units="h">
                    <circle class="progress-clock__ring" cx="128" cy="128" r="90" fill="none" opacity="0.1" stroke="url(#pc-yellow)" stroke-/>
                    <circle class="progress-clock__ring-fill" data-ring="d" cx="128" cy="128" r="90" fill="none" stroke="url(#pc-yellow)" stroke- stroke-dasharray="565.5 565.5" stroke-dashoffset="565.5" stroke-linecap="round" transform="rotate(-90,128,128)"/>
                </g>
                <!-- Minutes of Hour -->
                <g data-units="m">
                    <circle class="progress-clock__ring" cx="128" cy="128" r="106" fill="none" opacity="0.1" stroke="url(#pc-blue)" stroke-/>
                    <circle class="progress-clock__ring-fill" data-ring="h" cx="128" cy="128" r="106" fill="none" stroke="url(#pc-blue)" stroke- stroke-dasharray="666 666" stroke-dashoffset="666" stroke-linecap="round" transform="rotate(-90,128,128)"/>
                </g>
                <!-- Seconds of Minute -->
                <g data-units="s">
                    <circle class="progress-clock__ring" cx="128" cy="128" r="122" fill="none" opacity="0.1" stroke="url(#pc-purple)" stroke-/>
                    <circle class="progress-clock__ring-fill" data-ring="m" cx="128" cy="128" r="122" fill="none" stroke="url(#pc-purple)" stroke- stroke-dasharray="766.5 766.5" stroke-dashoffset="766.5" stroke-linecap="round" transform="rotate(-90,128,128)"/>
                </g>
            </svg>
        </div>
    </body>
        
        <script  type="text/javascript">
            window.addEventListener("DOMContentLoaded", ()=>{
                const clock = new ProgressClock("#clock");
            }
        );

        class ProgressClock {
            constructor(qs) {
                this.el = document.querySelector(qs);
                this.time = 0;
                this.updateTimeout = null;
                this.ringTimeouts = [];
                this.update();
            }
            getDayOfWeek(day) {
                switch (day) {
                case 1:
                    return "星期一";
                case 2:
                    return "星期二";
                case 3:
                    return "星期三";
                case 4:
                    return "星期四";
                case 5:
                    return "星期五";
                case 6:
                    return "星期六";
                default:
                    return "星期日";
                }
            }
            getMonthInfo(mo, yr) {
                switch (mo) {
                case 1:
                    return {
                        name: "2月",
                        days: yr % 4 === 0 ? 29 : 28
                    };
                case 2:
                    return {
                        name: "3月",
                        days: 31
                    };
                case 3:
                    return {
                        name: "4月",
                        days: 30
                    };
                case 4:
                    return {
                        name: "5月",
                        days: 31
                    };
                case 5:
                    return {
                        name: "6月",
                        days: 30
                    };
                case 6:
                    return {
                        name: "7月",
                        days: 31
                    };
                case 7:
                    return {
                        name: "8月",
                        days: 31
                    };
                case 8:
                    return {
                        name: "9月",
                        days: 30
                    };
                case 9:
                    return {
                        name: "10月",
                        days: 31
                    };
                case 10:
                    return {
                        name: "11月",
                        days: 30
                    };
                case 11:
                    return {
                        name: "12月",
                        days: 31
                    };
                default:
                    return {
                        name: "1月",
                        days: 31
                    };
                }
            }
            update() {
                this.time = new Date();

                if (this.el) {
                    // date and time
                    const dayOfWeek = this.time.getDay();
                    const year = this.time.getFullYear();
                    const month = this.time.getMonth();
                    const day = this.time.getDate();
                    const hr = this.time.getHours();
                    const min = this.time.getMinutes();
                    const sec = this.time.getSeconds();
                    const dayOfWeekName = this.getDayOfWeek(dayOfWeek);
                    const monthInfo = this.getMonthInfo(month, year);
                    const m_progress = sec / 60;
                    const h_progress = (min + m_progress) / 60;
                    const d_progress = (hr + h_progress) / 24;
                    const mo_progress = ((day - 1) + d_progress) / monthInfo.days;
                    const units = [{
                        label: "y",
                        value: year
                    }, {
                        label: "w",
                        value: dayOfWeekName
                    }, {
                        label: "mo",
                        value: monthInfo.name,
                        progress: mo_progress
                    }, {
                        label: "d",
                        value: day,
                        progress: d_progress
                    }, {
                        label: "h",
                        value: hr > 12 ? hr - 12 : hr,
                        progress: h_progress
                    }, {
                        label: "m",
                        value: min < 10 ? "0" + min : min,
                        progress: m_progress
                    }, {
                        label: "s",
                        value: sec < 10 ? "0" + sec : sec
                    }, {
                        label: "ap",
                        value: hr > 12 ? "PM" : "AM"
                    }];

                    // flush out the timeouts
                    this.ringTimeouts.forEach(t=>{
                        clearTimeout(t);
                    }
                    );
                    this.ringTimeouts = [];

                    // update the display
                    units.forEach(u=>{
                        // rings
                        const ring = this.el.querySelector(`[data-ring="${u.label}"]`);

                        if (ring) {
                            const strokeDashArray = ring.getAttribute("stroke-dasharray");
                            const fill360 = "progress-clock__ring-fill--360";

                            if (strokeDashArray) {
                                // calculate the stroke
                                const circumference = +strokeDashArray.split(" ")[0];
                                const strokeDashOffsetPct = 1 - u.progress;

                                ring.setAttribute("stroke-dashoffset", strokeDashOffsetPct * circumference);

                                // add the fade-out transition, then remove it
                                if (strokeDashOffsetPct === 1) {
                                    ring.classList.add(fill360);

                                    this.ringTimeouts.push(setTimeout(()=>{
                                        ring.classList.remove(fill360);
                                    }
                                    , 600));
                                }
                            }
                        }

                        // digits
                        const unit = this.el.querySelector(`[data-unit="${u.label}"]`);

                        if (unit)
                            unit.innerText = u.value;
                    }
                    );
                }

                clearTimeout(this.updateTimeout);
                this.updateTimeout = setTimeout(this.update.bind(this), 1e3);
            }
        }
        </script>
    
</html>
 
  • 本站名称:清风资源网
  • 本站永久地址:www.mcoxn.com
  • 本站提供的源码、模板、插件等等其他资源,除资源本身问题外,都不包含免费技术服务,请大家谅解!
  • 本站资源解压密码一般都为www.mcoxn.com如发现链接失效,请联系在线客服更新。
  • 本站所有代码模板仅供学习交流使用,请勿用于商业用途,及违法侵权行为使用均与本站无关。
  • 源码素材属于虚拟商品,具有可复制性,可传播性,一旦授予,不接受任何形式的退款、换货要求。
  • 本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。
  • 本站所有资源来源于公开互联网搜集和网友投稿提供,仅供个人学习研究使用,若本站收录的内容对您的版权或者利益造成损害,请提供相应的资质证明发邮件至kakbga@qq.com我们将于3个工作日内予以删除。