<div class="radar"></div>
<label class="mute">
<input type="checkbox" checked>
<img class="on" src="https://api.iconify.design/material-symbols:volume-up.svg?color=%23888888" alt="volume on">
<img class="off" src="https://api.iconify.design/material-symbols:volume-off.svg?color=%23888888" alt="volume off">
</label>
HTML
格式化
支持Emmet,输入 p 后按 Tab键试试吧!
<head> ... </head>
<body>
</body>
CSS
格式化
html, body {
height: 100vh;
}
body {
background: #001413;
overflow: hidden;
display: grid;
place-items: center;
}
.radar {
--size: 450px;
--color: #15fcd8;
width: var(--size);
height: var(--size);
margin: auto;
border: 3px solid var(--color);
border-radius: 50%;
background:
/* 4) guides */
linear-gradient(transparent 0 49.75%, var(--color) 49.75% 50%, transparent 50% 100%),
linear-gradient(to right, transparent 0 49.75%, var(--color) 49.75% 50%, transparent 50% 100%),
/* 3) radar */
radial-gradient(
transparent 0% 25%,
var(--color) 25.5% 25.75%, transparent 26% 50%,
var(--color) 50.5% 50.75%, transparent 51% 75%,
var(--color) 75.5% 75.75%, transparent 76% 100%),
/* 2.5) fondo tapar grid */
radial-gradient(#00767211, #002421 65%),
/* 2) grid */
repeating-linear-gradient(to right, #0e817a77 0 1px, transparent 1.5px 25px),
repeating-linear-gradient(#0e817a77 0 1px, transparent 1.5px 25px),
/* 1) background */
radial-gradient(#007672 0, #002421 65%);
position: relative;
mix-blend-mode: difference; /* color-dodge; */
}
.dot {
width: var(--size);
height: var(--size);
background: var(--color);
border-radius: 50%;
position: absolute;
filter: blur(1px);
opacity: 0.5;
left: var(--x);
top: var(--y);
animation: disappear 1s ease-in-out forwards;
}
.radar::before {
--dark-color: color-mix(in srgb, var(--color), transparent 85%);
content: "";
display: block;
background: var(--dark-color);
width: 100%;
height: 100%;
border-radius: 50%;
position: absolute;
filter: blur(1px);
animation: pulse 1.25s infinite 0.25s;
}
.radar::after {
--radar-color: color-mix(in srgb, var(--color), transparent 50%);
content: "";
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background: conic-gradient(transparent 0, var(--radar-color) 0.1turn 0.15turn, transparent 0.25turn);
mix-blend-mode: plus-lighter;
animation: move-radar 5s linear infinite;
}
@keyframes move-radar {
from { rotate: -0.125turn; }
to { rotate: 0.875turn; }
}
@keyframes pulse {
0% { scale: 1; }
100% { scale: 1.15; opacity: 0; }
}
@keyframes disappear {
to { opacity: 0; }
}
.mute {
position: absolute;
top: 1rem;
right: 1rem;
}
.mute {
cursor: pointer;
& input { display: none }
& img { width: 48px }
& input:checked ~ .on,
& input:not(:checked) ~ .off {
display: none;
}
}
JS
格式化
const radar = document.querySelector(".radar");
const muted = document.querySelector(".mute input");
/* https://freesound.org/people/unfa/sounds/584179/ */
const beep = new Audio("https://cdn.freesound.org/previews/584/584179_1038806-lq.mp3");
const addDot = () => {
if (Math.random() > 0.5) return;
const dot = document.createElement("div");
dot.classList.add("dot");
const x = Math.floor(Math.random() * 100);
const y = Math.floor(Math.random() * 100);
const size = 10 + Math.floor(Math.random() * 10);
dot.style.setProperty("--x", `${x}%`);
dot.style.setProperty("--y", `${y}%`);
dot.style.setProperty("--size", `${size}px`);
radar.append(dot);
setTimeout(() => dot.remove(), 2000);
}
setInterval(() => {
if (!muted.checked) {
beep.currentTime = 0;
beep.play();
}
addDot();
}, 1250);