aboutsummaryrefslogtreecommitdiff
path: root/static/js
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-11-03 19:00:29 -0500
committerBobby <[email protected]>2024-11-03 19:00:29 -0500
commitc0bd4e25dc6d1dbbe76cb88c36d74b621dbdb58c (patch)
treebf6f3e599df7b0e9053888b7f7dcbe9de6ac5aaf /static/js
parent609cc6264e8a9dfc69666b40f7452300ad22caef (diff)
downloadthatcomputerscientist-c0bd4e25dc6d1dbbe76cb88c36d74b621dbdb58c.tar.xz
thatcomputerscientist-c0bd4e25dc6d1dbbe76cb88c36d74b621dbdb58c.zip
stuff still all over the place; added a music player and a resolution based scaler — now in a brainfucked stated - going to sleep
Diffstat (limited to 'static/js')
-rw-r--r--static/js/musicPlayer.js540
-rw-r--r--static/js/shared/resolutionScaling.js136
-rw-r--r--static/js/youdontdare.js2
3 files changed, 677 insertions, 1 deletions
diff --git a/static/js/musicPlayer.js b/static/js/musicPlayer.js
new file mode 100644
index 00000000..bf1586b9
--- /dev/null
+++ b/static/js/musicPlayer.js
@@ -0,0 +1,540 @@
+// Collection of random anime artwork
+const artworkCollection = [
+ 'https://i.pinimg.com/enabled/564x/e2/5d/31/e25d3199f73c9453035727f8c7a70170.jpg',
+ 'https://i.pinimg.com/enabled/564x/5f/ed/28/5fed282cff8d22ac857e2a489031d05a.jpg',
+ 'https://i.pinimg.com/736x/05/a8/71/05a87162a78e2cad2ffe0a9eac6b4e2c.jpg',
+ 'https://i.pinimg.com/736x/c6/ac/13/c6ac139ed02c9accd34dbb16d7466025.jpg',
+ 'https://i.pinimg.com/736x/72/69/c3/7269c3d939764b024da9a6869dc59a0f.jpg',
+ 'https://i.pinimg.com/enabled/564x/cc/5c/6f/cc5c6f1c8e053d791ae2b4300ef5c9fe.jpg',
+ 'https://i.pinimg.com/enabled/564x/fa/0a/c2/fa0ac2b7145af1205c87350f7c735683.jpg',
+ 'https://i.pinimg.com/enabled/564x/94/84/57/9484579fcbf7e768d6206b07fa44c2b9.jpg',
+ 'https://i.pinimg.com/enabled/564x/fd/30/bf/fd30bf62f6409129ce6538f1b9ed7b8b.jpg',
+ 'https://i.pinimg.com/enabled/564x/44/b2/11/44b21104b4e41736c99ee183127aab3d.jpg',
+ 'https://i.pinimg.com/enabled/564x/f7/ce/56/f7ce5629aa91866020a559ef7e249f1c.jpg',
+ 'https://i.pinimg.com/enabled/564x/7b/ac/36/7bac368ff9b5f702d9b727491f8d4ef0.jpg',
+ 'https://i.pinimg.com/enabled/564x/39/1a/51/391a514a013f62ca9f25f47b4cbd7776.jpg',
+ 'https://i.pinimg.com/enabled/564x/03/d2/96/03d2967de5d249f88155cab461e69f3a.jpg'
+];
+
+// Constants
+const SEEKBAR_CONFIG = {
+ HEIGHT: 4,
+ THUMB_RADIUS: 6,
+ HOVER_RADIUS: 8,
+ COLORS: {
+ BASE: 'rgba(255, 255, 255, 0.5)',
+ PROGRESS: 'rgba(255, 255, 255, 1)',
+ HOVER: 'rgba(255, 255, 255, 0.8)'
+ }
+};
+
+const STORE_LIMIT = artworkCollection.length;
+const MIN_SCREEN_WIDTH = 1600;
+
+// Audio Context and Core Variables
+let audioContext;
+let sourceNode;
+let analyzerNode;
+let audioBuffer;
+let startTime;
+let pauseTime = 0;
+let isPlaying = false;
+let currentSong = null;
+let isLoading = true;
+let isDragging = false;
+
+// DOM Elements
+const elements = {
+ playButton: document.getElementById('song-play'),
+ prevButton: document.getElementById('song-prev'),
+ nextButton: document.getElementById('song-next'),
+ timeElapsed: document.getElementById('song-time-elapsed'),
+ timeTotal: document.getElementById('song-time-total'),
+ songCover: document.getElementById('song-cover'),
+ songTitle: document.getElementById('song-title'),
+ songArtistAlbum: document.getElementById('song-artist-album'),
+ visualizer: document.getElementById('song-visualizer')
+};
+
+// Create and setup seekbar
+const seekbarCanvas = document.createElement('canvas');
+seekbarCanvas.id = 'custom-seekbar';
+seekbarCanvas.width = 140;
+seekbarCanvas.height = 20;
+seekbarCanvas.style.cssText = 'position: absolute; left: 30px; top: 220px; cursor: pointer; z-index: 1;';
+document.getElementById('song-time').parentNode.insertBefore(seekbarCanvas, document.getElementById('song-time'));
+
+class ArtworkManager {
+ constructor() {
+ this.usedArtwork = new Set();
+ this.availableArtwork = [...artworkCollection];
+ }
+
+ getRandomArtwork() {
+ // If all artwork has been used, reset the pool
+ if (this.availableArtwork.length === 0) {
+ this.resetArtworkPool();
+ }
+
+ // Get random artwork from available pool
+ const randomIndex = Math.floor(Math.random() * this.availableArtwork.length);
+ const artwork = this.availableArtwork[randomIndex];
+
+ // Remove from available pool and add to used set
+ this.availableArtwork.splice(randomIndex, 1);
+ this.usedArtwork.add(artwork);
+
+ return artwork;
+ }
+
+ resetArtworkPool() {
+ this.availableArtwork = [...artworkCollection];
+ this.usedArtwork.clear();
+ }
+
+ releaseArtwork(artwork) {
+ if (this.usedArtwork.has(artwork)) {
+ this.usedArtwork.delete(artwork);
+ this.availableArtwork.push(artwork);
+ }
+ }
+}
+
+// Song Store Management
+class SongStore {
+ constructor() {
+ this.songs = JSON.parse(localStorage.getItem('songStore')) || [];
+ this.currentIndex = parseInt(localStorage.getItem('currentSongIndex')) || -1;
+ this.artworkCache = JSON.parse(localStorage.getItem('artworkCache')) || {};
+ this.artworkManager = new ArtworkManager();
+
+ // Restore artwork state
+ Object.values(this.artworkCache).forEach(artwork => {
+ this.artworkManager.usedArtwork.add(artwork);
+ });
+
+ // Remove any artwork from availableArtwork that's already in use
+ this.artworkManager.availableArtwork = this.artworkManager.availableArtwork
+ .filter(artwork => !this.artworkManager.usedArtwork.has(artwork));
+ }
+
+ async addSong(song) {
+ if (!song) return null;
+
+ // Generate unique artwork for the song
+ const artwork = this.artworkManager.getRandomArtwork();
+ this.artworkCache[song.id] = artwork;
+
+ // Always add the song, even if it's a duplicate
+ this.songs.push({
+ id: song.id,
+ title: song.title,
+ artist: song.artist,
+ album: song.album
+ });
+
+ // Maintain the store limit
+ if (this.songs.length > STORE_LIMIT) {
+ const removedSong = this.songs.shift();
+ // Release the artwork back to the pool
+ const removedArtwork = this.artworkCache[removedSong.id];
+ this.artworkManager.releaseArtwork(removedArtwork);
+ delete this.artworkCache[removedSong.id];
+ if (this.currentIndex > -1) this.currentIndex--;
+ }
+
+ this.currentIndex = this.songs.length - 1;
+ this.save();
+
+ return {
+ ...this.songs[this.currentIndex],
+ artwork: this.artworkCache[song.id]
+ };
+ }
+
+ async getNext() {
+ if (this.currentIndex < this.songs.length - 1) {
+ this.currentIndex++;
+ this.save();
+ return {
+ ...this.songs[this.currentIndex],
+ artwork: this.artworkCache[this.songs[this.currentIndex].id]
+ };
+ }
+ // Get new song if we're at the end
+ const newSong = await this.fetchNewSong();
+ return this.addSong(newSong);
+ }
+
+ async getPrevious() {
+ if (this.currentIndex > 0) {
+ this.currentIndex--;
+ this.save();
+ return {
+ ...this.songs[this.currentIndex],
+ artwork: this.artworkCache[this.songs[this.currentIndex].id]
+ };
+ }
+ return null;
+ }
+
+ async fetchNewSong() {
+ try {
+ const response = await fetch('/stream/random-song');
+ const data = await response.json();
+ return data.song;
+ } catch (error) {
+ console.error('Error fetching new song:', error);
+ return null;
+ }
+ }
+
+ save() {
+ localStorage.setItem('songStore', JSON.stringify(this.songs));
+ localStorage.setItem('currentSongIndex', this.currentIndex.toString());
+ localStorage.setItem('artworkCache', JSON.stringify(this.artworkCache));
+ }
+
+ getCurrentSong() {
+ if (this.currentIndex >= 0) {
+ const song = this.songs[this.currentIndex];
+ return {
+ ...song,
+ artwork: this.artworkCache[song.id]
+ };
+ }
+ return null;
+ }
+
+ getArtwork(songId) {
+ return this.artworkCache[songId];
+ }
+}
+
+const songStore = new SongStore();
+
+// Audio Control Functions
+async function initAudio() {
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
+ analyzerNode = audioContext.createAnalyser();
+ analyzerNode.fftSize = 256;
+ analyzerNode.connect(audioContext.destination);
+}
+
+function formatTime(time) {
+ const minutes = Math.floor(time / 60);
+ const seconds = Math.floor(time % 60).toString().padStart(2, '0');
+ return `${minutes}:${seconds}`;
+}
+
+async function fetchAudio(url) {
+ isLoading = true;
+ updateControls();
+ try {
+ const response = await fetch(url);
+ const arrayBuffer = await response.arrayBuffer();
+ audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
+ elements.timeTotal.textContent = formatTime(audioBuffer.duration);
+ isLoading = false;
+ updateControls();
+ } catch (error) {
+ console.error('Error loading audio:', error);
+ isLoading = false;
+ updateControls();
+ }
+}
+
+function playAudio(offset = 0) {
+ if (!audioBuffer) return;
+ if (isPlaying) stopAudio();
+
+ offset = Math.min(Math.max(0, offset), audioBuffer.duration);
+
+ sourceNode = audioContext.createBufferSource();
+ sourceNode.buffer = audioBuffer;
+ sourceNode.connect(analyzerNode);
+
+ sourceNode.onended = async () => {
+ const currentTime = audioContext.currentTime - startTime;
+ if (currentTime >= audioBuffer.duration - 0.1) {
+ await loadNewSong(true, 'next');
+ }
+ };
+
+ sourceNode.start(0, offset);
+ startTime = audioContext.currentTime - offset;
+ isPlaying = true;
+ updateUI();
+}
+
+function stopAudio() {
+ if (sourceNode) {
+ sourceNode.stop();
+ sourceNode = null;
+ isPlaying = false;
+ updateUI();
+ }
+}
+
+function seekAudio(time) {
+ if (!audioBuffer) return;
+ const wasPlaying = isPlaying;
+ stopAudio();
+ pauseTime = time;
+ if (wasPlaying) {
+ playAudio(pauseTime);
+ }
+ drawSeekbar();
+ savePlaybackState();
+}
+
+// UI Update Functions
+function updateUI() {
+ elements.playButton.innerHTML = isPlaying ? "&#10074;&#10074;" : "&#9658;";
+ drawVisualizer();
+ updateTimeDisplay();
+ drawSeekbar();
+}
+
+function updateControls() {
+ elements.playButton.disabled = isLoading;
+ elements.prevButton.disabled = isLoading;
+ elements.nextButton.disabled = isLoading;
+ if (isLoading) stopAudio();
+}
+
+function updateSongInfo() {
+ if (currentSong) {
+ elements.songTitle.textContent = currentSong.title;
+ elements.songArtistAlbum.textContent = `${currentSong.artist} - ${currentSong.album}`;
+ // Always update artwork with the cached version or generate new
+ elements.songCover.src = currentSong.artwork || songStore.getArtwork(currentSong.id);
+ }
+}
+
+// Canvas Drawing Functions
+function drawSeekbar() {
+ if (!audioBuffer) return;
+
+ const ctx = seekbarCanvas.getContext('2d');
+ const { width, height } = seekbarCanvas;
+ const centerY = height / 2;
+
+ ctx.clearRect(0, 0, width, height);
+
+ // Background bar
+ ctx.fillStyle = SEEKBAR_CONFIG.COLORS.BASE;
+ ctx.fillRect(0, centerY - SEEKBAR_CONFIG.HEIGHT / 2, width, SEEKBAR_CONFIG.HEIGHT);
+
+ // Progress bar
+ const currentTime = isPlaying ? audioContext.currentTime - startTime : pauseTime;
+ const progress = (currentTime / audioBuffer.duration) * width;
+
+ ctx.fillStyle = SEEKBAR_CONFIG.COLORS.PROGRESS;
+ ctx.fillRect(0, centerY - SEEKBAR_CONFIG.HEIGHT / 2, progress, SEEKBAR_CONFIG.HEIGHT);
+
+ // Thumb
+ ctx.beginPath();
+ ctx.arc(progress, centerY, SEEKBAR_CONFIG.THUMB_RADIUS, 0, Math.PI * 2);
+ ctx.fill();
+}
+
+function drawVisualizer() {
+ if (!isPlaying) return;
+
+ const ctx = elements.visualizer.getContext('2d');
+ const bufferLength = analyzerNode.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+
+ function animate() {
+ if (!isPlaying) return;
+ requestAnimationFrame(animate);
+
+ analyzerNode.getByteFrequencyData(dataArray);
+ ctx.clearRect(0, 0, elements.visualizer.width, elements.visualizer.height);
+
+ const barWidth = (elements.visualizer.width / bufferLength) * 2.5;
+ let x = 0;
+
+ for (let i = 0; i < bufferLength; i++) {
+ const barHeight = (dataArray[i] / 255) * elements.visualizer.height;
+ ctx.fillStyle = `rgb(${dataArray[i]}, 50, 255)`;
+ ctx.fillRect(x, elements.visualizer.height - barHeight, barWidth, barHeight);
+ x += barWidth + 1;
+ }
+ }
+
+ animate();
+}
+
+// State Management Functions
+function savePlaybackState() {
+ if (!currentSong) return;
+
+ const currentTime = isPlaying ? audioContext.currentTime - startTime : pauseTime;
+ const state = {
+ songId: currentSong.id,
+ timeStamp: Math.min(currentTime, audioBuffer?.duration || 0),
+ isPlaying,
+ artwork: elements.songCover.src,
+ songTitle: currentSong.title,
+ songArtist: currentSong.artist,
+ songAlbum: currentSong.album
+ };
+
+ localStorage.setItem('playbackState', JSON.stringify(state));
+}
+
+// Song Loading and Navigation
+async function loadNewSong(autoplay = false, direction = 'next') {
+ try {
+ const wasPlaying = isPlaying || autoplay;
+ stopAudio();
+
+ let nextSong;
+ if (direction === 'next') {
+ nextSong = await songStore.getNext();
+ } else {
+ nextSong = await songStore.getPrevious();
+ if (!nextSong) return; // Don't proceed if no previous song
+ }
+
+ currentSong = nextSong;
+ updateSongInfo(); // This will now use the cached artwork
+
+ await fetchAudio(`/stream/song/${currentSong.id}`);
+ pauseTime = 0; // Reset seek position for new song
+
+ if (wasPlaying) {
+ playAudio(0);
+ }
+
+ savePlaybackState();
+ } catch (error) {
+ console.error('Error loading song:', error);
+ }
+}
+
+function getCurrentScale() {
+ const screenWidth = window.innerWidth;
+ return screenWidth <= MIN_SCREEN_WIDTH ? 1 : screenWidth / MIN_SCREEN_WIDTH;
+}
+
+// Event Listeners
+function setupEventListeners() {
+ seekbarCanvas.addEventListener('mousedown', (e) => {
+ isDragging = true;
+ const scale = getCurrentScale();
+ const rect = seekbarCanvas.getBoundingClientRect();
+ // Adjust position calculation for scale
+ const position = Math.max(0, Math.min((e.clientX - rect.left) / scale, seekbarCanvas.width));
+ handleSeek(position);
+ });
+
+ seekbarCanvas.addEventListener('mousemove', (e) => {
+ if (isDragging) {
+ const scale = getCurrentScale();
+ const rect = seekbarCanvas.getBoundingClientRect();
+ // Adjust position calculation for scale
+ const position = Math.max(0, Math.min((e.clientX - rect.left) / scale, seekbarCanvas.width));
+ handleSeek(position);
+ }
+ });
+
+ seekbarCanvas.addEventListener('mouseup', () => isDragging = false);
+ seekbarCanvas.addEventListener('mouseleave', () => isDragging = false);
+ document.addEventListener('mouseup', () => isDragging = false);
+
+ // Rest of the event listeners remain the same...
+ elements.playButton.addEventListener('click', () => {
+ if (isLoading) return;
+ if (isPlaying) {
+ stopAudio();
+ pauseTime = audioContext.currentTime - startTime;
+ } else {
+ playAudio(pauseTime);
+ }
+ savePlaybackState();
+ });
+
+ elements.prevButton.addEventListener('click', () => loadNewSong(isPlaying, 'previous'));
+ elements.nextButton.addEventListener('click', () => loadNewSong(isPlaying, 'next'));
+
+ elements.songCover.addEventListener('error', () => {
+ elements.songCover.src = songStore.getArtwork(currentSong.id);
+ savePlaybackState();
+ });
+
+ document.addEventListener('visibilitychange', savePlaybackState);
+ window.addEventListener('beforeunload', savePlaybackState);
+}
+
+function handleSeek(position) {
+ if (!audioBuffer) return;
+ const seekTime = (position / seekbarCanvas.width) * audioBuffer.duration;
+ seekAudio(seekTime);
+}
+
+function updateTimeDisplay() {
+ if (!audioBuffer) return;
+ const currentTime = isPlaying ? audioContext.currentTime - startTime : pauseTime;
+ elements.timeElapsed.textContent = formatTime(currentTime);
+ elements.timeTotal.textContent = formatTime(audioBuffer.duration);
+}
+
+// Main update loop
+function update() {
+ if (audioBuffer && isPlaying) {
+ const currentTime = audioContext.currentTime - startTime;
+ if (currentTime >= audioBuffer.duration) {
+ loadNewSong(true, 'next');
+ return;
+ }
+ }
+
+ updateTimeDisplay();
+ drawSeekbar();
+ requestAnimationFrame(update);
+}
+
+// Initialization
+async function init() {
+ await initAudio();
+ setupEventListeners();
+
+ try {
+ const savedState = localStorage.getItem('playbackState');
+ if (savedState) {
+ const state = JSON.parse(savedState);
+ currentSong = {
+ id: state.songId,
+ title: state.songTitle,
+ artist: state.songArtist,
+ album: state.songAlbum,
+ artwork: state.artwork
+ };
+
+ updateSongInfo();
+ await fetchAudio(`/stream/song/${state.songId}`);
+ pauseTime = state.timeStamp || 0;
+
+ if (state.isPlaying) {
+ setTimeout(() => playAudio(pauseTime), 100);
+ } else {
+ drawSeekbar();
+ updateTimeDisplay();
+ }
+ } else {
+ await loadNewSong(false);
+ }
+ } catch (error) {
+ console.error('Error restoring state:', error);
+ await loadNewSong(false);
+ }
+
+ setInterval(savePlaybackState, 500);
+ update();
+}
+
+init();
+
diff --git a/static/js/shared/resolutionScaling.js b/static/js/shared/resolutionScaling.js
new file mode 100644
index 00000000..f11bc9a8
--- /dev/null
+++ b/static/js/shared/resolutionScaling.js
@@ -0,0 +1,136 @@
+(function () {
+ // Core configuration constants
+ const SITE_BASE_WIDTH = 1000;
+ const MIN_SCALE_WIDTH = 1600; // Threshold for starting scale adjustments
+ const HI_RES_WIDTH = 1920; // Threshold for forcing maximum resolution
+ const MAX_DENSITY = 3; // Maximum supported image density
+
+ // Calculate appropriate image density based on screen size and device
+ function getTargetDensity() {
+ const screenWidth = window.innerWidth;
+ const devicePixelRatio = window.devicePixelRatio || 1;
+
+ if (screenWidth < MIN_SCALE_WIDTH) return 1;
+ if (screenWidth >= HI_RES_WIDTH) return MAX_DENSITY;
+
+ const scaleRatio = screenWidth / MIN_SCALE_WIDTH;
+ const effectiveScale = scaleRatio * devicePixelRatio;
+
+ return effectiveScale > 2 ? 2 : 1;
+ }
+
+ // Update single image to appropriate resolution
+ function forceHighResImage(img) {
+ const srcset = img.getAttribute('srcset');
+ if (!srcset) return;
+
+ const sources = srcset.split(',').map(src => {
+ const [url, size] = src.trim().split(' ');
+ return {
+ url: url,
+ density: parseFloat(size.replace('x', '')) || 1
+ };
+ }).sort((a, b) => b.density - a.density);
+
+ const targetDensity = getTargetDensity();
+ const targetSource = sources.reduce((prev, curr) => {
+ if (curr.density <= targetDensity && curr.density > prev.density) {
+ return curr;
+ }
+ return prev;
+ }, { density: 0 });
+
+ if (img.src !== targetSource.url) {
+ const newImg = document.createElement('img');
+ Array.from(img.attributes).forEach(attr => {
+ if (attr.name !== 'src' && attr.name !== 'srcset') {
+ newImg.setAttribute(attr.name, attr.value);
+ }
+ });
+ newImg.src = targetSource.url;
+ img.parentNode.replaceChild(newImg, img);
+ }
+ }
+
+ // Update all images on the page
+ function updateAllImages() {
+ document.querySelectorAll('img[srcset]').forEach(forceHighResImage);
+ }
+
+ // Calculate and apply scaling based on screen width
+ function calculateScale() {
+ const screenWidth = window.innerWidth;
+ const wrapper = document.getElementById('body-wrapper');
+ if (!wrapper) return;
+
+ if (screenWidth <= MIN_SCALE_WIDTH) {
+ wrapper.style.transform = 'scale(1)';
+ wrapper.style.transformOrigin = 'left top';
+ wrapper.style.left = '50%';
+ wrapper.style.marginLeft = `-${SITE_BASE_WIDTH / 2}px`;
+ return;
+ }
+
+ const scaleRatio = screenWidth / MIN_SCALE_WIDTH;
+ const scaledWidth = SITE_BASE_WIDTH * scaleRatio;
+ const leftPosition = (screenWidth - scaledWidth) / 2;
+
+ wrapper.style.transform = `scale(${scaleRatio})`;
+ wrapper.style.transformOrigin = 'left top';
+ wrapper.style.left = `${leftPosition}px`;
+ wrapper.style.position = 'absolute';
+ wrapper.style.marginLeft = '0';
+ }
+
+ // Initialize wrapper positioning and initial calculations
+ function init() {
+ const wrapper = document.getElementById('body-wrapper');
+ if (wrapper) {
+ wrapper.style.position = 'absolute';
+ wrapper.style.width = `${SITE_BASE_WIDTH}px`;
+ wrapper.style.top = '0';
+ }
+
+ calculateScale();
+ updateAllImages();
+ }
+
+ // Handle dynamically added images
+ const observer = new MutationObserver((mutations) => {
+ mutations.forEach(mutation => {
+ mutation.addedNodes.forEach(node => {
+ if (node.nodeType === 1) {
+ if (node.tagName === 'IMG' && node.hasAttribute('srcset')) {
+ forceHighResImage(node);
+ }
+ node.querySelectorAll('img[srcset]').forEach(forceHighResImage);
+ }
+ });
+ });
+ });
+
+ // Debounced resize handler
+ let resizeTimeout;
+ function handleResize() {
+ clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(() => {
+ calculateScale();
+ updateAllImages();
+ }, 100);
+ }
+
+ // Event listeners and initialization
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', () => {
+ init();
+ observer.observe(document.body, { childList: true, subtree: true });
+ });
+ } else {
+ init();
+ observer.observe(document.body, { childList: true, subtree: true });
+ }
+
+ window.addEventListener('load', init);
+ window.addEventListener('resize', handleResize);
+ window.addEventListener('orientationchange', handleResize);
+})(); \ No newline at end of file
diff --git a/static/js/youdontdare.js b/static/js/youdontdare.js
index 8e0c8aa4..c2a27ac1 100644
--- a/static/js/youdontdare.js
+++ b/static/js/youdontdare.js
@@ -73,7 +73,7 @@ function applyStyles(x, y, container) {
container.style.position = 'absolute'
container.style.top = `${y}px`
container.style.left = `${x}px`
- container.style.fontSize = '8px'
+ container.style.fontSize = '11px'
container.style.userSelect = 'none'
container.style.transition = 'opacity 0.5s ease-in-out'
container.style.textShadow = '0 0 2px #e014df, 0 0 4px #e014df, 0 0 6px #e014df, 0 0 10px #ff00ff, 0 0 14px #ff00ff'