wip: test
This commit is contained in:
70
web/bg.js
70
web/bg.js
@@ -1 +1,69 @@
|
|||||||
(()=>{var s="#dce0e8",l="#45475a",R=1*devicePixelRatio,i=document.getElementById("bg"),n=i.getContext("2d"),r=0,h=0,a="#dce0e8";function w(e,t){let o=window.devicePixelRatio||1;i.style.width=`${e}px`,i.style.height=`${t}px`,i.width=e*o,i.height=t*o}function f(){n.clearRect(0,0,i.width,i.height)}function m(e,t){let o=Math.sqrt((e-r)**2+(t-h)**2),d=100,v=R+2*devicePixelRatio*((d-Math.min(o,d))/d);n.beginPath(),n.arc(e,t,v,0,2*Math.PI,!1),n.fillStyle=a,n.fill()}function c(){f();for(let e=0;e<i.width;e+=10*devicePixelRatio)for(let t=0;t<i.height;t+=10*devicePixelRatio)m(e,t)}window.addEventListener("resize",()=>{w(window.innerWidth,window.innerHeight),c()});window.addEventListener("mousemove",e=>{r=e.clientX*devicePixelRatio,h=e.clientY*devicePixelRatio,c()});if(window.matchMedia){let e=window.matchMedia("(prefers-color-scheme: dark)");a=e.matches?l:s,e.addEventListener("change",t=>{a=t.matches?l:s,c()})}w(window.innerWidth,window.innerHeight);c();})();
|
const DOT_COLOR_LIGHT_MODE = "#dce0e8";
|
||||||
|
const DOT_COLOR_DARK_MODE = "#45475a";
|
||||||
|
const DOT_RADIUS = 1 * devicePixelRatio;
|
||||||
|
|
||||||
|
const canvas = document.getElementById("bg");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
let mouseX = 0;
|
||||||
|
let mouseY = 0;
|
||||||
|
let dotColor = "#dce0e8";
|
||||||
|
|
||||||
|
function resizeCanvas(width, height) {
|
||||||
|
const devicePixelRatio = window.devicePixelRatio || 1;
|
||||||
|
canvas.style.width = `${width}px`;
|
||||||
|
canvas.style.height = `${height}px`;
|
||||||
|
canvas.width = width * devicePixelRatio;
|
||||||
|
canvas.height = height * devicePixelRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCanvas() {
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawDot(x, y) {
|
||||||
|
const distance = Math.sqrt((x - mouseX) ** 2 + (y - mouseY) ** 2);
|
||||||
|
const effectRadius = 100;
|
||||||
|
const radius =
|
||||||
|
DOT_RADIUS +
|
||||||
|
2 *
|
||||||
|
devicePixelRatio *
|
||||||
|
((effectRadius - Math.min(distance, effectRadius)) / effectRadius);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
|
||||||
|
ctx.fillStyle = dotColor;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawPattern() {
|
||||||
|
clearCanvas();
|
||||||
|
for (let x = 0; x < canvas.width; x += 10 * devicePixelRatio) {
|
||||||
|
for (let y = 0; y < canvas.height; y += 10 * devicePixelRatio) {
|
||||||
|
drawDot(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
resizeCanvas(window.innerWidth, window.innerHeight);
|
||||||
|
drawPattern();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("mousemove", (event) => {
|
||||||
|
mouseX = event.clientX * devicePixelRatio;
|
||||||
|
mouseY = event.clientY * devicePixelRatio;
|
||||||
|
drawPattern();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.matchMedia) {
|
||||||
|
const query = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
dotColor = query.matches ? DOT_COLOR_DARK_MODE : DOT_COLOR_LIGHT_MODE;
|
||||||
|
|
||||||
|
query.addEventListener("change", (event) => {
|
||||||
|
dotColor = event.matches ? DOT_COLOR_DARK_MODE : DOT_COLOR_LIGHT_MODE;
|
||||||
|
drawPattern();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeCanvas(window.innerWidth, window.innerHeight);
|
||||||
|
drawPattern();
|
||||||
|
132
web/script.js
132
web/script.js
@@ -1 +1,131 @@
|
|||||||
(()=>{var u=document.getElementById("play-btn"),r=document.getElementsByClassName("cat")[0],s=document.getElementById("volume-slider"),v=document.getElementById("current-volume-label"),p=new Audio("./audio/click.wav"),f=new Audio("./audio/click-release.wav"),m=5e3,a=20,A=6e4,i=!1,o=!1,e,l=100,t=0;function d(){e=new Audio(`./current.mp3?t=${Date.now()}`),e.onplay=()=>{i=!0,u.innerText="pause"},e.onpause=()=>{i=!1,t=0,u.innerText="play"},e.onended=()=>{t=0,d()},e.volume=0,e.play(),y(),setTimeout(()=>{S()},A-m)}function I(){e.pause(),e.volume=0,t=0}function y(){o=!0;let n=l/(m/a),c=setInterval(()=>{t+=n,t>=l?(clearInterval(c),t=l,o=!1):e.volume=t/100},a)}function S(){o=!0;let n=l/(m/a),c=setInterval(()=>{t-=n,t<=0?(clearInterval(c),t=0,o=!1):e.volume=t/100},a)}function g(){let n=0;setInterval(()=>{n===3?n=0:n+=1,r.src=`./images/cat-${n}.png`},500)}u.onmousedown=()=>{p.play(),document.addEventListener("mouseup",()=>{f.play()},{once:!0})};u.onclick=()=>{i?I():d()};s.oninput=()=>{l=s.value,v.textContent=`${l}%`,!o&&e&&(e.volume=l/100,t=l)};s.value=100;g();})();
|
const playBtn = document.getElementById("play-btn");
|
||||||
|
const catImg = document.getElementsByClassName("cat")[0];
|
||||||
|
const volumeSlider = document.getElementById("volume-slider");
|
||||||
|
const currentVolumeLabel = document.getElementById("current-volume-label");
|
||||||
|
// const clickAudio = new Audio("./audio/click.wav");
|
||||||
|
// const clickReleaseAudio = new Audio("./audio/click-release.wav");
|
||||||
|
const clickAudio = new Audio();
|
||||||
|
const clickReleaseAudio = new Audio();
|
||||||
|
|
||||||
|
const CROSSFADE_DURATION_MS = 5000;
|
||||||
|
const CROSSFADE_INTERVAL_MS = 20;
|
||||||
|
const AUDIO_DURATION_MS = 60000;
|
||||||
|
|
||||||
|
let isPlaying = false;
|
||||||
|
let isFading = false;
|
||||||
|
let currentAudio;
|
||||||
|
let maxVolume = 100;
|
||||||
|
let currentVolume = 0;
|
||||||
|
|
||||||
|
function playAudio() {
|
||||||
|
// add a random query parameter at the end to prevent browser caching
|
||||||
|
currentAudio = new Audio(`./current.mp3?t=${Date.now()}`);
|
||||||
|
currentAudio.onplay = () => {
|
||||||
|
isPlaying = true;
|
||||||
|
playBtn.innerText = "pause";
|
||||||
|
};
|
||||||
|
currentAudio.onpause = () => {
|
||||||
|
isPlaying = false;
|
||||||
|
currentVolume = 0;
|
||||||
|
playBtn.innerText = "play";
|
||||||
|
};
|
||||||
|
currentAudio.onended = () => {
|
||||||
|
currentVolume = 0;
|
||||||
|
playAudio();
|
||||||
|
};
|
||||||
|
currentAudio.volume = 0;
|
||||||
|
|
||||||
|
currentAudio.play();
|
||||||
|
|
||||||
|
fadeIn();
|
||||||
|
setTimeout(() => {
|
||||||
|
fadeOut();
|
||||||
|
}, AUDIO_DURATION_MS - CROSSFADE_DURATION_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pauseAudio() {
|
||||||
|
currentAudio.pause();
|
||||||
|
currentAudio.volume = 0;
|
||||||
|
currentVolume = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fadeIn() {
|
||||||
|
isFading = true;
|
||||||
|
|
||||||
|
// volume ranges from 0 to 100, this determines by how much the volume number
|
||||||
|
// should be incremented at every step of the fade in
|
||||||
|
const volumeStep =
|
||||||
|
maxVolume / (CROSSFADE_DURATION_MS / CROSSFADE_INTERVAL_MS);
|
||||||
|
const handle = setInterval(() => {
|
||||||
|
currentVolume += volumeStep;
|
||||||
|
if (currentVolume >= maxVolume) {
|
||||||
|
clearInterval(handle);
|
||||||
|
currentVolume = maxVolume;
|
||||||
|
isFading = false;
|
||||||
|
} else {
|
||||||
|
currentAudio.volume = currentVolume / 100;
|
||||||
|
}
|
||||||
|
}, CROSSFADE_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fadeOut() {
|
||||||
|
isFading = true;
|
||||||
|
|
||||||
|
// volume ranges from 0 to 100, this determines by how much the volume number
|
||||||
|
// should be decremented at every step of the fade out
|
||||||
|
const volumeStep =
|
||||||
|
maxVolume / (CROSSFADE_DURATION_MS / CROSSFADE_INTERVAL_MS);
|
||||||
|
const handle = setInterval(() => {
|
||||||
|
currentVolume -= volumeStep;
|
||||||
|
if (currentVolume <= 0) {
|
||||||
|
clearInterval(handle);
|
||||||
|
currentVolume = 0;
|
||||||
|
isFading = false;
|
||||||
|
} else {
|
||||||
|
currentAudio.volume = currentVolume / 100;
|
||||||
|
}
|
||||||
|
}, CROSSFADE_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function animateCat() {
|
||||||
|
let current = 0;
|
||||||
|
setInterval(() => {
|
||||||
|
if (current === 3) {
|
||||||
|
current = 0;
|
||||||
|
} else {
|
||||||
|
current += 1;
|
||||||
|
}
|
||||||
|
catImg.src = `./images/cat-${current}.png`;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
playBtn.onmousedown = () => {
|
||||||
|
clickAudio.play();
|
||||||
|
document.addEventListener(
|
||||||
|
"mouseup",
|
||||||
|
() => {
|
||||||
|
clickReleaseAudio.play();
|
||||||
|
},
|
||||||
|
{ once: true },
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
playBtn.onclick = () => {
|
||||||
|
if (isPlaying) {
|
||||||
|
pauseAudio();
|
||||||
|
} else {
|
||||||
|
playAudio();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
volumeSlider.oninput = () => {
|
||||||
|
maxVolume = volumeSlider.value;
|
||||||
|
currentVolumeLabel.textContent = `${maxVolume}%`;
|
||||||
|
if (!isFading && currentAudio) {
|
||||||
|
currentAudio.volume = maxVolume / 100;
|
||||||
|
currentVolume = maxVolume;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
volumeSlider.value = 100;
|
||||||
|
animateCat();
|
||||||
|
Reference in New Issue
Block a user