马黑黑 发表于 2024-10-9 21:02

SVG石英钟(初稿)

<style>
#hHand, #mHand, #sHand { animation: turning var(--dur) linear infinite; }
#hHand { --begin: 0deg; --dur: 216000s; }
#mHand { --begin: 0deg; --dur: 3600s; }
#sHand { --begin: 0deg; --dur: 60s; }
#kedu {
        font: normal 16px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
        text-anchor: middle;
        dominant-baseline: middle;
        fill: red;
        user-select: none;
}
@keyframes turning {
        from { transform: rotate(var(--begin)); }
        to { transform: rotate(calc(360deg + var(--begin))); }
}
</style>

<div style="margin: 30px; text-align:center;">
        <svg id="clock" width="300" height="300" viewBox="-100 -100 200 200">
                <defs>
                        <linearGradient id="bg" x1="0" x2="1" y1="0" y2="1">
                                <stop offset="0%" stop-color="red" />
                                <stop offset="50%" stop-color="green" />
                                <stop offset="100%" stop-color="navy" />
                        </linearGradient>
                        <path id="tpath" d="M-85 0 A85 85 0 1 1 85 0 A85 85 0 1 1 -85 0" />
                </defs>
                <circle cx="0" cy="0" r="95" fill="skyblue" stroke="url(#bg)" stroke-width="10" />
                <g id="kedu">
                        <text font-size="14" fill="white" text-anchor="middle">
                                <tspan id="tdate" x="5" y="-35">日期</tspan>
                                <tspan id="tday" x="0" y="-15">星期</tspan>
                                <tspan x="0" y="40" fill="gray">HUACHAO</tspan>
                        </text>
                </g>
                <line id="hHand" x1="0" y1="0" x2="0" y2="-65" stroke="whitesmoke" stroke-width="4" />
                <line id="mHand" x1="0" y1="0" x2="0" y2="-75" stroke="snow" stroke-width="3" />
                <line id="sHand" x1="0" y1="0" x2="0" y2="-85" stroke="white" stroke-width="2" />
                <circle cx="0" cy="0" r="6" fill="red" stroke="white" stroke-width="2" />
        </svg>
</div>

<script>
mkScale = (total=60) => {
        let deg = 360 / total;
        Array(total).fill('').forEach((l,k) => {
                let w = -6;
                if(k % 5 === 0) {
                        let t = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                        t.setAttribute('transform', `rotate(${deg * k - 60} 0 0) translate(75) rotate(${-1 * (deg * k - 60)} 0 0)`);
                        t.textContent = k / 5 + 1;
                        kedu.appendChild(t);
                        w = -4;
                }
                l = document.createElementNS('http://www.w3.org/2000/svg', 'line');
                l.setAttribute('transform', `rotate(${deg * k - 60} 0 0) translate(90)`);
                l.setAttribute('x1', '0');
                l.setAttribute('y1', '0');
                l.setAttribute('x2', w);
                l.setAttribute('y2', '0');
                l.setAttribute('stroke', 'teal');
                kedu.appendChild(l);
        });
};

setTime = () => {
        let now = new Date();
        let hr = now.getHours() > 12 ? now.getHours() - 12 : now.getHours(),
                min = now.getMinutes(),
                sec = now.getSeconds(),
                msec = now.getMilliseconds();
        let hDeg = hr * 30 + (min * 6 / 12),
                mDeg = min * 6 + (sec * 6 / 60),
                sDeg = sec * 6 + (msec * 0.36 / 1000);
        hHand.style.setProperty('--begin', hDeg + 'deg');
        mHand.style.setProperty('--begin', mDeg + 'deg');
        sHand.style.setProperty('--begin', sDeg + 'deg');
};

setDate = () => {
        var sDate = new Date();
        var sDateS = sDate.getSeconds()*1000,
                sDateMs = sDate.getMilliseconds();
        tdate.textContent = `${sDate.getFullYear()}年${sDate.getMonth() + 1}月${sDate.getDate()}日`;
        tday.textContent = `星期${'日一二三四五六'.substr(sDate.getDay(),1)}`;
        setTimeout( () => {
                setDate();
        }, 3600000 - sDateS - sDateMs);
};

mkScale();
setTime();
setDate();
</script>

马黑黑 发表于 2024-10-9 21:03

<h2>完整代码</h2>
<div class="hE"><pre>
&lt;style&gt;
#hHand, #mHand, #sHand { animation: turning var(--dur) linear infinite; }
#hHand { --begin: 0deg; --dur: 216000s; }
#mHand { --begin: 0deg; --dur: 3600s; }
#sHand { --begin: 0deg; --dur: 60s; }
#kedu {
        font: normal 16px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
        text-anchor: middle;
        dominant-baseline: middle;
        fill: red;
        user-select: none;
}
@keyframes turning {
        from { transform: rotate(var(--begin)); }
        to { transform: rotate(calc(360deg + var(--begin))); }
}
&lt;/style&gt;

&lt;div style="margin: 30px; text-align:center;"&gt;
        &lt;svg id="clock" width="300" height="300" viewBox="-100 -100 200 200"&gt;
                &lt;defs&gt;
                        &lt;linearGradient id="bg" x1="0" x2="1" y1="0" y2="1"&gt;
                                &lt;stop offset="0%" stop-color="red" /&gt;
                                &lt;stop offset="50%" stop-color="green" /&gt;
                                &lt;stop offset="100%" stop-color="navy" /&gt;
                        &lt;/linearGradient&gt;
                        &lt;path id="tpath" d="M-85 0 A85 85 0 1 1 85 0 A85 85 0 1 1 -85 0" /&gt;
                &lt;/defs&gt;
                &lt;circle cx="0" cy="0" r="95" fill="skyblue" stroke="url(#bg)" stroke-width="10" /&gt;
                &lt;g id="kedu"&gt;
                        &lt;text font-size="14" fill="white" text-anchor="middle"&gt;
                                &lt;tspan id="tdate" x="5" y="-35"&gt;日期&lt;/tspan&gt;
                                &lt;tspan id="tday" x="0" y="-15"&gt;星期&lt;/tspan&gt;
                                &lt;tspan x="0" y="40" fill="gray"&gt;HUACHAO&lt;/tspan&gt;
                        &lt;/text&gt;
                &lt;/g&gt;
                &lt;line id="hHand" x1="0" y1="0" x2="0" y2="-65" stroke="whitesmoke" stroke-width="4" /&gt;
                &lt;line id="mHand" x1="0" y1="0" x2="0" y2="-75" stroke="snow" stroke-width="3" /&gt;
                &lt;line id="sHand" x1="0" y1="0" x2="0" y2="-85" stroke="white" stroke-width="2" /&gt;
                &lt;circle cx="0" cy="0" r="6" fill="red" stroke="white" stroke-width="2" /&gt;
        &lt;/svg&gt;
&lt;/div&gt;

&lt;script&gt;
mkScale = (total=60) =&gt; {
        let deg = 360 / total;
        Array(total).fill('').forEach((l,k) =&gt; {
                let w = -6;
                if(k % 5 === 0) {
                        let t = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                        t.setAttribute('transform', `rotate(${deg * k - 60} 0 0) translate(75) rotate(${-1 * (deg * k - 60)} 0 0)`);
                        t.textContent = k / 5 + 1;
                        kedu.appendChild(t);
                        w = -4;
                }
                l = document.createElementNS('http://www.w3.org/2000/svg', 'line');
                l.setAttribute('transform', `rotate(${deg * k - 60} 0 0) translate(90)`);
                l.setAttribute('x1', '0');
                l.setAttribute('y1', '0');
                l.setAttribute('x2', w);
                l.setAttribute('y2', '0');
                l.setAttribute('stroke', 'teal');
                kedu.appendChild(l);
        });
};

setTime = () =&gt; {
        let now = new Date();
        let hr = now.getHours() &gt; 12 ? now.getHours() - 12 : now.getHours(),
                min = now.getMinutes(),
                sec = now.getSeconds(),
                msec = now.getMilliseconds();
        let hDeg = hr * 30 + (min * 6 / 12),
                mDeg = min * 6 + (sec * 6 / 60),
                sDeg = sec * 6 + (msec * 0.36 / 1000);
        hHand.style.setProperty('--begin', hDeg + 'deg');
        mHand.style.setProperty('--begin', mDeg + 'deg');
        sHand.style.setProperty('--begin', sDeg + 'deg');
};

setDate = () =&gt; {
        var sDate = new Date();
        var sDateS = sDate.getSeconds()*1000,
                sDateMs = sDate.getMilliseconds();
        tdate.textContent = `${sDate.getFullYear()}年${sDate.getMonth() + 1}月${sDate.getDate()}日`;
        tday.textContent = `星期${'日一二三四五六'.substr(sDate.getDay(),1)}`;
        setTimeout( () =&gt; {
                setDate();
        }, 3600000 - sDateS - sDateMs);
};

mkScale();
setTime();
setDate();
&lt;/script&gt;
</pre></div>

<script>
var sc = document.createElement('script');
sc.chartset = 'utf-8';
sc.src = 'https://638183.freep.cn/638183/web/js2024/helight.js';
document.body.appendChild(sc);
</script>

马黑黑 发表于 2024-10-9 21:11

石英钟指针通常平滑运行,所以使用CSS关键帧动画驱动。每次运行时钟页面之时,JS给出相关CSS变量,然后纯粹由CSS动画驱动时分秒三个指针的运作。

出于布局需要,svg的 viewBox 200*200的尺寸,同时坐标系设为宽高各一半的负数值。

每到整点,setDate函数都会工作一次,它的任务是给出日期和星期信息。这样可以保证跨日时日期星期信息能跟进。

醉美水芙蓉 发表于 2024-10-9 21:11

红影 发表于 2024-10-9 21:30

没5分钟的刻度线还缩短了一点,更清楚呢。{:4_187:}

红影 发表于 2024-10-9 21:31

又是一个漂亮的花潮时钟,这个太棒了{:4_199:}

红影 发表于 2024-10-9 21:35

还是渐变边框呢。
当下的年月日时都能被调用,这个太牛了,以前就觉得牛,现在这个svg的也觉得牛{:4_199:}

红影 发表于 2024-10-9 21:36

看到这个,先拿来对应自己电脑上的时间了,真不错,还挺准的{:4_173:}

马黑黑 发表于 2024-10-9 22:12

红影 发表于 2024-10-9 21:36
看到这个,先拿来对应自己电脑上的时间了,真不错,还挺准的

JS获取的是本地时间

马黑黑 发表于 2024-10-9 22:15

红影 发表于 2024-10-9 21:35
还是渐变边框呢。
当下的年月日时都能被调用,这个太牛了,以前就觉得牛,现在这个svg的也觉得牛

svg有较好的构图能力,毕竟它就是基于矢量图像的。svg时钟放大缩小都挺好:本稿,基于 200*200,画布可以缩放到任意合理的宽高一致的尺寸

红影 发表于 2024-10-9 22:37

马黑黑 发表于 2024-10-9 22:12
JS获取的是本地时间

原来如此。不过大多数的电脑手机时间最多差个几秒而已{:4_173:}

红影 发表于 2024-10-9 22:38

马黑黑 发表于 2024-10-9 22:15
svg有较好的构图能力,毕竟它就是基于矢量图像的。svg时钟放大缩小都挺好:本稿,基于 200*200,画布可以 ...

嗯嗯,可以任意缩放的好,这个时钟外形很漂亮。{:4_199:}

花飞飞 发表于 2024-10-9 22:52

即时时间哎。。。
不同方法得到时钟,三种还是四种啊。。
看到时间提醒,真不早了。。明天细看代码。。{:4_173:}

马黑黑 发表于 2024-10-9 23:12

红影 发表于 2024-10-9 22:37
原来如此。不过大多数的电脑手机时间最多差个几秒而已

Windows时钟会自动校时,非常准

马黑黑 发表于 2024-10-9 23:13

红影 发表于 2024-10-9 22:38
嗯嗯,可以任意缩放的好,这个时钟外形很漂亮。

就是有JS在里面,存为 .svg 不管用

马黑黑 发表于 2024-10-9 23:14

花飞飞 发表于 2024-10-9 22:52
即时时间哎。。。
不同方法得到时钟,三种还是四种啊。。
看到时间提醒,真不早了。。明天细看代码。。{: ...

CSS+HTML的,基于canvas画布的,现在这个svg的

马黑黑 发表于 2024-10-9 23:19

红影 发表于 2024-10-9 22:38
嗯嗯,可以任意缩放的好,这个时钟外形很漂亮。

时钟一般都是漂亮的

红影 发表于 2024-10-9 23:20

马黑黑 发表于 2024-10-9 23:12
Windows时钟会自动校时,非常准

这个太棒了{:4_187:}

红影 发表于 2024-10-9 23:21

马黑黑 发表于 2024-10-9 23:13
就是有JS在里面,存为 .svg 不管用

那就不存为.svg,直接用代码呗{:4_173:}

红影 发表于 2024-10-9 23:22

马黑黑 发表于 2024-10-9 23:19
时钟一般都是漂亮的

又漂亮又实用呢{:4_199:}
页: [1] 2 3 4
查看完整版本: SVG石英钟(初稿)