本代码是根据开源代码 Clock Shop 将原生的进行转换成的vue3写法,如果需要更多的样式
可以参观 Clock Shop
https://drawcall.github.io/clock-shop/index.html 文档自己进行适配
效果展示
网站效果展示:后台管理系统 (hvercel.cn)https://hvercel.cn/login
表盘1代码:
<!-- https://drawcall.github.io/clock-shop/index.html -->
<template>
<div>
<div class="fill">
<div class="reference"></div>
<div class="clock" ref="clockRef">
<div class="centre">
<div class="dynamic"></div>
<div class="expand round circle-1"></div>
<div class="anchor hour">
<div class="element thin-hand"></div>
<div class="element fat-hand"></div>
</div>
<div class="anchor minute">
<div class="element thin-hand"></div>
<div class="element fat-hand minute-hand"></div>
</div>
<div class="anchor second">
<div class="element second-hand"></div>
</div>
<div class="expand round circle-2"></div>
<div class="expand round circle-3"></div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="">
import { ref, onMounted, onBeforeUnmount } from "vue";
const clockRef = ref(null);
onMounted(() => {
utilityClock(clockRef.value);
autoResize(clockRef.value, 295 + 32);
});
function utilityClock(container) {
console.log(container);
var dynamic = container.querySelector(".dynamic");
var hourElement = container.querySelector(".hour");
var minuteElement = container.querySelector(".minute");
var secondElement = container.querySelector(".second");
var minute = function (n) {
return n % 5 == 0 ? minuteText(n) : minuteLine(n);
};
var minuteText = function (n) {
var element = document.createElement("div");
element.className = "minute-text";
element.innerHTML = (n < 10 ? "0" : "") + n;
position(element, n / 60, 135);
dynamic.appendChild(element);
};
var minuteLine = function (n) {
var anchor = document.createElement("div");
anchor.className = "anchor";
var element = document.createElement("div");
element.className = "element minute-line";
rotate(anchor, n);
anchor.appendChild(element);
dynamic.appendChild(anchor);
};
var hour = function (n) {
var element = document.createElement("div");
element.className = "hour-text hour-" + n;
element.innerHTML = n;
position(element, n / 12, 105);
dynamic.appendChild(element);
};
var position = function (element, phase, r) {
var theta = phase * 2 * Math.PI;
element.style.top = (-r * Math.cos(theta)).toFixed(1) + "px";
element.style.left = (r * Math.sin(theta)).toFixed(1) + "px";
};
var rotate = function (element, second) {
element.style.transform = element.style.webkitTransform =
"rotate(" + second * 6 + "deg)";
};
var animate = function () {
var now = new Date();
var time =
now.getHours() * 3600 +
now.getMinutes() * 60 +
now.getSeconds() * 1 +
now.getMilliseconds() / 1000;
rotate(secondElement, time);
rotate(minuteElement, time / 60);
rotate(hourElement, time / 60 / 12);
requestAnimationFrame(animate);
};
for (var i = 1; i <= 60; i++) minute(i);
for (var i = 1; i <= 12; i++) hour(i);
animate();
}
function autoResize(element, nativeSize) {
var update = function () {
var parent = element.offsetParent;
var scale = Math.min(parent?.offsetWidth, parent.offsetHeight) / nativeSize;
element.style.transform = element.style.webkitTransform =
"scale(" + scale.toFixed(3) + ")";
};
update();
window.addEventListener("resize", update);
}
</script>
<style>
.hour-text {
position: absolute;
font: 40px Hei, Helvetica, Arial, sans-serif;
color: white;
transform: translate(-50%, -50%);
height: auto;
}
.hour-10 {
padding-left: 0.4ex;
}
.hour-11 {
padding-left: 0.25ex;
}
.minute-hand {
height: 112px !important;
}
.minute-text {
position: absolute;
font: 12px Avenir Next, Helvetica, Arial, sans-serif;
color: white;
transform: translate(-50%, -50%);
}
.minute-line {
background: white;
width: 1px;
height: 9px;
transform: translate(-50%, -100%) translateY(-131px);
opacity: 0.34;
}
.anchor {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
}
</style>
<style scoped>
.fill {
position: relative;
width: 200px;
height: 200px;
background: black;
}
.clock {
position: absolute;
opacity: 1;
}
.fill .clock {
left: 50%;
top: 50%;
}
.centre {
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
}
.expand {
position: absolute;
top: 0;
left: 0;
transform: translate(-50%, -50%);
}
.element {
position: absolute;
top: 0;
left: 0;
}
.round {
border-radius: 296px;
}
.circle-1 {
background: white;
width: 12px;
height: 12px;
}
.circle-2 {
background: #fa9f22;
width: 8px;
height: 8px;
}
.circle-3 {
background: black;
width: 4px;
height: 4px;
}
.second {
transform: rotate(180deg);
}
.minute {
transform: rotate(54deg);
}
.second-hand {
width: 2px;
height: 164px;
background: #fa9f22;
transform: translate(-50%, -100%) translateY(24px);
}
.hour {
transform: rotate(304.5deg);
}
.thin-hand {
width: 4px;
height: 50px;
background: white;
transform: translate(-50%, -100%);
}
.fat-hand {
width: 10px;
height: 57px;
border-radius: 10px;
background: white;
transform: translate(-50%, -100%) translateY(-18px);
}
</style>
表盘2代码
<template>
<div class="clock_box pr">
<h1 class="off">C<span>LOCK</span></h1>
<div id="clock">
<ul id="s"></ul>
<ul id="m"></ul>
<ul id="h"></ul>
</div>
</div>
</template>
<script setup>
import $ from "jquery";
function draw() {
let D;
for (var i = 0; i < 60; i++) {
D = i < 10 ? "0" + i : i;
$("#s").append("<li data-item=" + D + ">" + D + "</li>");
}
for (var i = 0; i < 60; i++) {
D = i < 10 ? "0" + i : i;
$("#m").append("<li data-item=" + D + ">" + D + "</li>");
}
for (var i = 0; i < 24; i++) {
D = i < 10 ? "0" + i : i;
$("#h").append("<li data-item=" + D + ">" + D + "</li>");
}
}
function place() {
let hdeg = 15;
let msdeg = 6;
$("#s li").each(function (index) {
$(this).css({
transform:
"rotateZ(" + msdeg * index + "deg) translateX(" + parseInt(130) + "px)",
});
});
$("#m li").each(function (index) {
$(this).css({
transform:
"rotateZ(" + msdeg * index + "deg) translateX(" + parseInt(105) + "px)",
});
});
$("#h li").each(function (index) {
$(this).css({
transform:
"rotateZ(" + hdeg * index + "deg) translateX(" + parseInt(80) + "px)",
});
});
}
//TIMER
function sec(ts, timer) {
let TS = ts % 60;
if (ts == 0 && timer) min(0, timer);
let deg = (360 / 60) * ts;
$("#s li").removeClass("active");
$("#s li").eq(TS).addClass("active");
$("#s").css({ transform: "rotateZ(-" + deg + "deg)" });
ts++;
if (timer)
setTimeout(function () {
sec(ts, timer);
}, TIME * 1000);
}
function min(tm, timer) {
let TM = tm % 60;
if (tm == 0 && timer) hour(0, timer);
let deg = (360 / 60) * tm;
$("#m li").removeClass("active");
$("#m li").eq(TM).addClass("active");
$("#m").css({ transform: "rotateZ(-" + deg + "deg)" });
tm++;
if (timer)
setTimeout(function () {
min(tm, timer);
}, TIME * 60000);
}
function hour(th, timer) {
let TH = th % 24;
let deg = (360 / 24) * th;
$("#h li").removeClass("active");
$("#h li").eq(TH).addClass("active");
$("#h").css({ transform: "rotateZ(-" + deg + "deg)" });
th++;
if (timer)
setTimeout(function () {
hour(th, timer);
}, TIME * 3600000);
}
//CLOCK
function clock() {
let d = new Date();
let H = d.getHours();
let M = d.getMinutes();
let S = d.getSeconds();
hour(H, 0);
min(M, 0);
sec(S, 0);
setTimeout(function () {
clock();
}, 1000);
}
$(document).ready(function () {
draw();
place();
//TIMER
/*
TIME = 1;
sec(0,1);
*/
//CLOCK
clock();
//LIGHT
$("h1").click(function () {
$(this).toggleClass("off");
});
});
</script>
<style lang="less" scoped>
h1.off + #clock {
background-image: linear-gradient(
60deg,
rgba(255, 255, 255, 0.05) 0%,
rgba(255, 255, 255, 0.7) 40%,
rgba(255, 255, 255, 0.5) 45%,
rgba(255, 255, 255, 0.25) 55%,
rgba(255, 255, 255, 0.35) 55.5%,
rgba(255, 255, 255, 0.3) 60%,
rgba(255, 255, 255, 0.2) 68%,
rgba(255, 255, 255, 0.1) 72%,
rgba(255, 255, 255, 0.25) 75%,
rgba(255, 255, 255, 0) 100%
),
radial-gradient(
circle at 50% 10%,
rgba(180, 180, 180, 1) 0%,
rgba(140, 140, 140, 1) 80%
);
box-shadow: inset 0 10px 10px 0px rgba(0, 0, 0, 0.35),
inset 0 -3px 1px rgba(222, 220, 210, 1),
0 1px 0 1px rgba(255, 255, 255, 0.5), 0 0 0px 10px rgba(222, 98, 0, 0.3),
0 0 0 11px rgba(255, 255, 255, 0.5), 0 30px 50px 20px rgba(0, 0, 0, 0.5);
}
// :deep(.clock_box) {
h1 {
margin: 0;
font-family: "Montserrat";
position: absolute;
top: 50%;
left: 50%;
height: 100px;
width: 60px;
text-align: center;
line-height: 120px;
font-size: 80px;
font-weight: 400;
color: rgba(230, 230, 230, 1);
text-shadow: 0 0px 50px rgba(255, 255, 255, 0.75),
0 0px 150px rgba(255, 255, 255, 0.5), 0 0px 200px rgba(255, 255, 255, 0);
transform: translate(-55%, -50%);
transform-origin: 50%;
cursor: pointer;
z-index: 100;
transition: all 0.25s;
}
h1.off {
color: transparent;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.35),
0 -1px 1px rgba(0, 0, 0, 0.15);
}
h1 span {
font-size: 30px;
display: block;
position: absolute;
top: 0;
left: 25px;
}
#clock {
position: relative;
top: 150px;
left: 150px;
width: 300px;
height: 300px;
border-radius: 50%;
transform: translate(-50%, -50%);
z-index: 1;
}
#clock::after {
content: "";
position: absolute;
border: 1px solid #000;
width: 80px;
height: 30px;
transition-origin: 50%;
top: 50%;
left: 52%;
box-shadow: inset 0 0 20px 0px rgba(255, 255, 255, 1),
0 0 100px 1000px rgba(0, 0, 0, 0.75);
transition: all 0.5s;
transform: translate(60px, -50%);
}
#clock::before {
content: "";
position: absolute;
border: 1px dashed #000;
border-top: 0;
border-bottom: 0;
width: 26px;
height: 10px;
right: -12px;
top: 50%;
margin: -5px 44px 0 0;
animation: pulse 1s infinite;
}
h1.off + #clock::after {
box-shadow: 0 0 100px 1000px rgba(0, 0, 0, 0), 0 0px 1px rgba(0, 0, 0, 0.25);
background: linear-gradient(
to bottom,
rgba(255, 255, 255, 0.65) 0%,
rgba(255, 255, 255, 0) 40%,
rgba(255, 255, 255, 0) 60%,
rgba(255, 255, 255, 0.15) 100%
);
border: 1px solid rgba(0, 0, 0, 0);
border-bottom: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
}
h1.off + #clock::before {
border: 1px dashed rgba(80, 80, 80, 1);
border-top: 0;
border-bottom: 0;
opacity: 1;
animation: none;
}
ul {
position: absolute;
margin: 0;
padding: 0;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
list-style: none;
margin: -10px 0 0 -10px;
}
#s,
#m,
#h {
transform: rotateZ(0deg);
transition: all 0.5s cubic-bezier(0.5, -0.5, 0.5, 1.5);
}
:deep(li) {
position: absolute;
transition: all 0.25s;
width: 20px;
height: 20px;
line-height: 20px;
text-align: right;
opacity: 0.2;
transform-origin: 50%;
transition: all 0.25s linear 0.25s;
&.active {
color: #424242;
opacity: 1;
font-weight: 700;
font-size: 18px;
}
}
@keyframes pulse {
0%,
50% {
opacity: 1;
}
51%,
100% {
opacity: 0;
}
}
// }
</style>