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>
<h2>完整代码</h2>
<div class="hE"><pre>
<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>
</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>
石英钟指针通常平滑运行,所以使用CSS关键帧动画驱动。每次运行时钟页面之时,JS给出相关CSS变量,然后纯粹由CSS动画驱动时分秒三个指针的运作。
出于布局需要,svg的 viewBox 200*200的尺寸,同时坐标系设为宽高各一半的负数值。
每到整点,setDate函数都会工作一次,它的任务是给出日期和星期信息。这样可以保证跨日时日期星期信息能跟进。 没5分钟的刻度线还缩短了一点,更清楚呢。{:4_187:} 又是一个漂亮的花潮时钟,这个太棒了{:4_199:} 还是渐变边框呢。
当下的年月日时都能被调用,这个太牛了,以前就觉得牛,现在这个svg的也觉得牛{:4_199:} 看到这个,先拿来对应自己电脑上的时间了,真不错,还挺准的{:4_173:} 红影 发表于 2024-10-9 21:36
看到这个,先拿来对应自己电脑上的时间了,真不错,还挺准的
JS获取的是本地时间 红影 发表于 2024-10-9 21:35
还是渐变边框呢。
当下的年月日时都能被调用,这个太牛了,以前就觉得牛,现在这个svg的也觉得牛
svg有较好的构图能力,毕竟它就是基于矢量图像的。svg时钟放大缩小都挺好:本稿,基于 200*200,画布可以缩放到任意合理的宽高一致的尺寸 马黑黑 发表于 2024-10-9 22:12
JS获取的是本地时间
原来如此。不过大多数的电脑手机时间最多差个几秒而已{:4_173:} 马黑黑 发表于 2024-10-9 22:15
svg有较好的构图能力,毕竟它就是基于矢量图像的。svg时钟放大缩小都挺好:本稿,基于 200*200,画布可以 ...
嗯嗯,可以任意缩放的好,这个时钟外形很漂亮。{:4_199:} 即时时间哎。。。
不同方法得到时钟,三种还是四种啊。。
看到时间提醒,真不早了。。明天细看代码。。{:4_173:} 红影 发表于 2024-10-9 22:37
原来如此。不过大多数的电脑手机时间最多差个几秒而已
Windows时钟会自动校时,非常准 红影 发表于 2024-10-9 22:38
嗯嗯,可以任意缩放的好,这个时钟外形很漂亮。
就是有JS在里面,存为 .svg 不管用 花飞飞 发表于 2024-10-9 22:52
即时时间哎。。。
不同方法得到时钟,三种还是四种啊。。
看到时间提醒,真不早了。。明天细看代码。。{: ...
CSS+HTML的,基于canvas画布的,现在这个svg的 红影 发表于 2024-10-9 22:38
嗯嗯,可以任意缩放的好,这个时钟外形很漂亮。
时钟一般都是漂亮的 马黑黑 发表于 2024-10-9 23:12
Windows时钟会自动校时,非常准
这个太棒了{:4_187:} 马黑黑 发表于 2024-10-9 23:13
就是有JS在里面,存为 .svg 不管用
那就不存为.svg,直接用代码呗{:4_173:} 马黑黑 发表于 2024-10-9 23:19
时钟一般都是漂亮的
又漂亮又实用呢{:4_199:}