Loading...

文章背景图

Obsidian 进度时钟组件

2026-07-21
0
- 字
- 分钟
|

Obsidian 进度时钟组件

const container = dv.container.createEl("div");
container.id = "clock";
container.className = "progress-clock";
if (container.parentElement) {
    container.parentElement.style.overflow = "visible";
    container.parentElement.style.overflowX = "visible";
    container.parentElement.style.overflowY = "visible";
}

let date = new Date();

function updateClock() {
    date = new Date();
    const formatDate = moment(date).locale('zh-cn').format("dddd-MMMM-D-H-mm-ss-a").split("-");
    const secProgress = parseInt(formatDate[5]) / 60;
    const minProgress = parseInt(formatDate[4]) / 60;
    const hourProgress = parseInt(formatDate[3]) / 24;
    const dayProgress = parseInt(formatDate[2]) / 31;

    container.innerHTML = `
        <button class="progress-clock__time-date" data-group="d" type="button">
            <small data-unit="w">${formatDate[0]}</small><br/>
            <span data-unit="mo">${formatDate[1]}</span>
            <span data-unit="d">${formatDate[2]}</span>
        </button>
        <button class="progress-clock__time-digit" data-unit="h" data-group="h" type="button">${formatDate[3]}</button><span class="progress-clock__time-colon">:</span>
        <button class="progress-clock__time-digit" data-unit="m" data-group="m" type="button">${formatDate[4]}</button><span class="progress-clock__time-colon">:</span>
        <button class="progress-clock__time-digit" data-unit="s" data-group="s" type="button">${formatDate[5]}</button>
        <span class="progress-clock__time-ampm" data-unit="ap">${formatDate[6]}</span>
        <svg class="progress-clock__rings" width="256" height="256" 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%)" />
                    <stop offset="100%" stop-color="hsl(323,90%)" />
                </linearGradient>
                <linearGradient id="pc-yellow" x1="1" y1="0.5" x2="0" y2="0.5">
                    <stop offset="0%" stop-color="hsl(43,90%)" />
                    <stop offset="100%" stop-color="hsl(23,90%)" />
                </linearGradient>
                <linearGradient id="pc-blue" x1="1" y1="0.5" x2="0" y2="0.5">
                    <stop offset="0%" stop-color="hsl(223,90%)" />
                    <stop offset="100%" stop-color="hsl(203,90%)" />
                </linearGradient>
                <linearGradient id="pc-purple" x1="1" y1="0.5" x2="0" y2="0.5">
                    <stop offset="0%" stop-color="hsl(283,90%)" />
                    <stop offset="100%" stop-color="hsl(263,90%)" />
                </linearGradient>
            </defs>
            <g data-units="d">
                <circle class="progress-clock__ring" cx="128" cy="128" r="74" fill="none" opacity="0.1" stroke="#e13e78" stroke-width="12" />
                <circle class="progress-clock__ring-fill" data-ring="mo" cx="128" cy="128" r="74" fill="none" stroke="#e13e78" stroke-width="12" stroke-dasharray="465 465" stroke-dashoffset="${(1 - dayProgress) * 465}" stroke-linecap="round" transform="rotate(-90,128,128)" />
            </g>
            <g data-units="h">
                <circle class="progress-clock__ring" cx="128" cy="128" r="90" fill="none" opacity="0.1" stroke="#e79742" stroke-width="12" />
                <circle class="progress-clock__ring-fill" data-ring="d" cx="128" cy="128" r="90" fill="none" stroke="#e79742" stroke-width="12" stroke-dasharray="565.5 565.5" stroke-dashoffset="${(1 - hourProgress) * 565.5}" stroke-linecap="round" transform="rotate(-90,128,128)" />
            </g>
            <g data-units="m">
                <circle class="progress-clock__ring" cx="128" cy="128" r="106" fill="none" opacity="0.1" stroke="#4483ec" stroke-width="12" />
                <circle class="progress-clock__ring-fill" data-ring="h" cx="128" cy="128" r="106" fill="none" stroke="#4483ec" stroke-width="12" stroke-dasharray="666 666" stroke-dashoffset="${(1 - minProgress) * 666}" stroke-linecap="round" transform="rotate(-90,128,128)" />
            </g>
            <g data-units="s">
                <circle class="progress-clock__ring" cx="128" cy="128" r="122" fill="none" opacity="0.1" stroke="#8f30eb" stroke-width="12" />
                <circle class="progress-clock__ring-fill" data-ring="m" cx="128" cy="128" r="122" fill="none" stroke="#8f30eb" stroke-width="12" stroke-dasharray="766.5 766.5" stroke-dashoffset="${(1 - secProgress) * 766.5}" stroke-linecap="round" transform="rotate(-90,128,128)" />
            </g>
        </svg>
    `;
}

updateClock();
setInterval(updateClock, 1000);

// Add CSS styles
const style = document.createElement('style');
style.textContent = `
.progress-clock {
    display: grid;
    justify-content: center;
    align-content: center;
    position: relative;
    text-align: center;
    height: 15em;
    margin-top: 0.5em;
}
.progress-clock button{
    padding: 0;
}
.progress-clock button:hover {
    background-color: transparent;
}
.progress-clock__time-date,
.progress-clock__time-digit,
.progress-clock__time-colon,
.progress-clock__time-ampm {
    font: 1em/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    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: 1.6em;
    font-weight: 400;
    grid-row: 2;
    margin: 0;
    transition: all 0.5s ease-in-out; /* Smooth transition for digits */
}
.progress-clock__time-colon {
    line-height: calc(var(--font-text-size)*1.5);
}
.is-mobile .progress-clock__time-colon {
    line-height: 2.5em;
    font-size: 16px;
}
.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;
    opacity: 0.6;
}
.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%);
}
[data-group="h"]:focus,
[data-group="h"]:hover {
    color: hsl(33,90%);
}
[data-group="m"]:focus,
[data-group="m"]:hover {
    color: hsl(213,90%);
}
[data-group="s"]:focus,
[data-group="s"]:hover {
    color: hsl(273,90%);
}
[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;
}
#clock button:not(.clickable-icon)
{
  box-shadow: none;
  background-color:transparent;
  display: block;
}

@keyframes electron-pulse {
    0% {
        transform: translate(-50%, -50%) scale(0.5);
        opacity: 0;
        border-color: rgba(255, 255, 255, 0.8); /* Initial color */
    }
    25% {
        transform: translate(-50%, -50%) scale(1);
        opacity: 1;
        border-color: rgba(255, 0, 0, 0.7); /* Midway color change */
    }
    50% {
        transform: translate(-50%, -50%) scale(1.5);
        opacity: 0.8;
        border-color: rgba(0, 255, 255, 0.6); /* Another color change */
    }
    75% {
        transform: translate(-50%, -50%) scale(2);
        opacity: 0.5;
        border-color: rgba(255, 0, 255, 0.5); /* Yet another color change */
    }
    100% {
        transform: translate(-50%, -50%) scale(2.5);
        opacity: 0;
        border-color: rgba(255, 255, 255, 0); /* Final color */
    }
}


`;
document.head.appendChild(style);
原创

Obsidian 进度时钟组件

本文链接: Obsidian 进度时钟组件

本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

评论交流

文章目录