CSS3和JS制作超酷霓虹电子钟效果

当前位置:主页 > CSS3库 > CSS3动画 > CSS3和JS制作超酷霓虹电子钟效果
CSS3和JS制作超酷霓虹电子钟效果
分享:

    插件介绍

    这是一款CSS3和JS制作超酷霓虹电子钟效果。该电子时钟通过HTML和CSS代码构建霓虹灯效果的电子时钟,并通过简单的JS代码来驱动电子时钟的运动。

    浏览器兼容性

    浏览器兼容性
    时间:12-06
    阅读:
简要教程

这是一款CSS3和JS制作超酷霓虹电子钟效果。该电子时钟通过HTML和CSS代码构建霓虹灯效果的电子时钟,并通过简单的JS代码来驱动电子时钟的运动。

使用方法

HTML代码
<main>
   <div class="clock" role="img">
       <div class="clock__ticks">
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
           <div class="clock__tick"></div>
       </div>
       <div class="clock__hands">
           <div class="clock__hand clock__hand--h"></div>
           <div class="clock__hand clock__hand--m"></div>
           <div class="clock__hand clock__hand--s" data-hand="s"></div>
       </div>
   </div>
</main>
		

CSS代码

* {
	border: 0;
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}
:root {
	--hue: 223;
	--hue1: 243;
	--hue2: 303;
	--bg: hsl(var(--hue),10%,5%);
	--fg: hsl(var(--hue),10%,95%);
	--primary: hsl(var(--hue),90%,50%);
	--trans-dur: 0.3s;
	font-size: calc(16px + (24 - 16) * (100vw - 320px) / (2560 - 320));
}
.container {
	background:
		radial-gradient(circle at center,hsla(0,0%,0%,0.5) 8em,hsla(0,0%,0%,0.8) 12em),
		url(../img/bricks.jpg) center / 16.9em 20em;
	color: var(--fg);
	display: flex;
	font: 1em/1.5 sans-serif;
	height: 70vh;
	min-height: 375px;
	transition:
		background-color var(--trans-dur),
		color var(--trans-dur);
}
main {
	margin: auto;
	padding: 1.5em 0;
}
.clock {
	--hrAngle: 0;
	--minAngle: 0;
	--secAngle: 0;
	position: relative;
	width: 16em;
	height: 16em;
}
.clock:before,
.clock:after,
.clock__ticks,
.clock__tick,
.clock__hands,
.clock__hand {
	position: absolute;
}
.clock:before,
.clock:after {
	border-radius: 50%;
	box-shadow:
		0 0 0 0.25em hsl(var(--hue1),90%,95%) inset,
		0 0 1.5em 0.5em hsla(var(--hue1),90%,50%,0.7) inset,
		0 0 1.5em 0.25em hsla(var(--hue1),90%,50%,0.7),
		0 0 7.5em hsla(var(--hue1),90%,50%,0.5) inset,
		0 0 7.5em hsla(var(--hue1),90%,50%,0.5);
	content: "";
	display: block;
}
.clock:before {
	width: 100%;
	height: 100%;
}
.clock:after {
	inset: 8%;
}
.clock__ticks,
.clock__hands {
	z-index: 1;
}
.clock__ticks {
	width: 100%;
	height: 100%;
}
.clock__tick {
	background-color: hsl(0,0%,95%);
	border-radius: 0.2em;
	box-shadow: 0 0 0.75em 0.25em hsla(0,0%,50%,0.7);
	top: calc(50% - 0.6em);
	left: calc(50% - 0.2em);
	width: 0.4em;
	height: 1.2em;
	transform-origin: 50% 50%;
}
.clock__tick:nth-child(3n + 1) {
	border-radius: 0.375em;
	box-shadow:
		0 0 0 0.25em hsl(0,0%,95%) inset,
		0 0 0.75em 0.5em hsla(0,0%,50%,0.7) inset,
		0 0 0.75em 0.25em hsla(0,0%,50%,0.7),
		0 0 4.5em hsla(0,0%,50%,0.5);
	top: calc(50% - 0.75em);
	left: calc(50% - 0.375em);
	width: 0.75em;
	height: 1.5em;
}
.clock__tick:nth-child(1) { transform: translateY(-5.25em); }
.clock__tick:nth-child(2) { transform: rotate(30deg) translateY(-5.25em); }
.clock__tick:nth-child(3) { transform: rotate(60deg) translateY(-5.25em); }
.clock__tick:nth-child(4) { transform: rotate(90deg) translateY(-5.25em); }
.clock__tick:nth-child(5) { transform: rotate(120deg) translateY(-5.25em); }
.clock__tick:nth-child(6) { transform: rotate(150deg) translateY(-5.25em); }
.clock__tick:nth-child(7) { transform: rotate(180deg) translateY(-5.25em); }
.clock__tick:nth-child(8) { transform: rotate(210deg) translateY(-5.25em); }
.clock__tick:nth-child(9) { transform: rotate(240deg) translateY(-5.25em); }
.clock__tick:nth-child(10) { transform: rotate(270deg) translateY(-5.25em); }
.clock__tick:nth-child(11) { transform: rotate(300deg) translateY(-5.25em); }
.clock__tick:nth-child(12) { transform: rotate(330deg) translateY(-5.25em); }

.clock__hands {
	border-radius: 50%;
	box-shadow: 0 0 0 0.25em hsl(var(--hue2),90%,95%) inset;
	filter:
		drop-shadow(0 0 0.125em hsl(var(--hue2),90%,50%))
		drop-shadow(0 0 0.75em hsl(var(--hue2),90%,50%));
	top: calc(50% - 0.75em);
	left: calc(50% - 0.75em);
	width: 1.5em;
	height: 1.5em;
}
.clock__hand {
	bottom: 50%;
	transform-origin: 50% 100%;
}
.clock__hand--h {
	border-radius: 0.5em 0.5em 0 0;
	box-shadow: 0 0 0 0.25em hsl(var(--hue2),90%,95%) inset;
	left: calc(50% - 0.4em);
	width: 0.8em;
	height: 2.5em;
	transform: rotate(var(--hrAngle)) translateY(-0.5em);
}
.clock__hand--m {
	border-radius: 0.5em 0.5em 0 0;
	box-shadow: 0 0 0 0.25em hsl(var(--hue2),90%,95%) inset;
	left: calc(50% - 0.4em);
	width: 0.8em;
	height: 3.75em;
	transform: rotate(var(--minAngle)) translateY(-0.5em);
}
.clock__hand--s {
	background-color: hsl(var(--hue2),90%,95%);
	border-radius: 0.2em 0.2em 0 0;
	left: calc(50% - 0.2em);
	width: 0.4em;
	height: 3.75em;
	transform: rotate(var(--secAngle)) translateY(-0.5em);
}
		

JS代码

window.addEventListener("DOMContentLoaded", () => {
  const c = new Clock11(".clock");
});

class Clock11 {
  constructor(el) {
    this.el = document.querySelector(el);

    this.init();
  }
  init() {
    this.timeUpdate();
  }
  get timeAsObject() {
    const date = new Date();
    const h = date.getHours();
    const m = date.getMinutes();
    const s = date.getSeconds();

    return { h, m, s };
  }
  get timeAsString() {
    const [h, m, s, ap] = this.timeDigitsGrouped;

    return `${h}:${m}:${s} ${ap}`;
  }
  get timeDigitsGrouped() {
    // this accessible string uses the 12-hour clock
    let { h, m, s } = this.timeAsObject;
    const ap = h > 11 ? "PM" : "AM";
    // deal with midnight
    if (h === 0) h += 12;else
    if (h > 12) h -= 12;
    // prepend 0 to the minute and second if single digits
    if (m < 10) m = `0${m}`;
    if (s < 10) s = `0${s}`;

    return [h, m, s, ap];
  }
  animateHand(hand) {
    const time = this.timeAsObject;
    const minFraction = time.s / 60;
    const angleB = Utils.decPlaces(360 * minFraction, 3);
    const angleA = angleB - 6;

    this.el?.querySelector(`[data-hand="${hand}"]`)?.animate(
    [
    { transform: `rotate(${angleA}deg) translateY(-0.5em)` },
    { transform: `rotate(${angleB}deg) translateY(-0.5em)` }],

    { duration: 300, easing: "cubic-bezier(0.77,0,0.18,1)" });

  }
  timeUpdate() {
    // update the accessible timestamp in the `aria-label`
    this.el?.setAttribute("aria-label", this.timeAsString);
    // move the hands
    const time = this.timeAsObject;
    const minFraction = time.s / 60;
    const hrFraction = (time.m + minFraction) / 60;
    const twelveHrFraction = (time.h + hrFraction) / 12;

    this.el?.style.setProperty("--secAngle", `${Utils.decPlaces(360 * minFraction, 3)}deg`);
    this.el?.style.setProperty("--minAngle", `${Utils.decPlaces(360 * hrFraction, 3)}deg`);
    this.el?.style.setProperty("--hrAngle", `${Utils.decPlaces(360 * twelveHrFraction, 3)}deg`);

    this.animateHand("s");
    // loop
    clearTimeout(this.timeUpdateLoop);
    this.timeUpdateLoop = setTimeout(this.timeUpdate.bind(this), 1e3);
  }}

class Utils {
  static decPlaces(n, d) {
    return Math.round(n * 10 ** d) / 10 ** d;
}}
		

codepen网址:https://codepen.io/jkantner/details/MWZxXKP