diff --git a/beango/css/beango.css b/beango/css/beango.css index 41331d2..69445af 100644 --- a/beango/css/beango.css +++ b/beango/css/beango.css @@ -16,6 +16,8 @@ body { .bingo-board { display: grid; gap: 4px; /* Adjust gap as needed */ + position: relative; /* Ensure it establishes a stacking context */ + z-index: 1; /* Place above the container's ::before pseudo-element */ } .centered { display: flex; @@ -158,6 +160,25 @@ body { /* Basic styling for the board */ #bingo-board-container { /* Background color/image/opacity set by JS */ + position: relative; /* Needed for pseudo-element positioning */ + overflow: hidden; /* Clip pseudo-element */ +} + +/* NEW: Pseudo-element for board background image */ +#bingo-board-container::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: var(--board-bg-image-url, none); + background-size: cover; + background-position: center center; + background-repeat: no-repeat; + opacity: var(--board-bg-image-opacity, 1); + z-index: 0; /* Default layer, behind explicit z-index on board */ + border-radius: inherit; /* Inherit border radius from container */ } /* Styling for config pane sections */ diff --git a/beango/images/redx.svg b/beango/images/redx.svg new file mode 100644 index 0000000..af0f810 --- /dev/null +++ b/beango/images/redx.svg @@ -0,0 +1,22 @@ + + + + diff --git a/beango/index.html b/beango/index.html index 32498e2..ddc98af 100644 --- a/beango/index.html +++ b/beango/index.html @@ -396,6 +396,12 @@

If set, opacity still applies to the image.

+ +
+ + +
+ diff --git a/beango/js/beango.js b/beango/js/beango.js index df4a0d0..e2a4ccc 100644 --- a/beango/js/beango.js +++ b/beango/js/beango.js @@ -45,6 +45,7 @@ const LS_MARKED_BORDER_WIDTH = 'beango_markedBorderWidth'; const LS_BOARD_BG_COLOR = 'beango_boardBgColor'; const LS_BOARD_BG_COLOR_OPACITY = 'beango_boardBgColorOpacity'; // (replaces LS_BOARD_BG_OPACITY) const LS_BOARD_BG_IMAGE_URL = 'beango_boardBgImageUrl'; +const LS_BOARD_BG_IMAGE_OPACITY = 'beango_boardBgImageOpacity'; // NEW const LS_MARKED_CELL_TEXT_COLOR = 'beango_markedCellTextColor'; const LS_MARKED_CELL_TEXT_OPACITY = 'beango_markedCellTextOpacity'; const LS_MARKED_CELL_OUTLINE_COLOR = 'beango_markedCellOutlineColor'; @@ -101,6 +102,7 @@ const DEFAULT_MARKED_BORDER_WIDTH = 0; // No border for marked cells const DEFAULT_BOARD_BG_COLOR = '#ffffff'; // Default white const DEFAULT_BOARD_BG_COLOR_OPACITY = 100; // (replaces DEFAULT_BOARD_BG_OPACITY) const DEFAULT_BOARD_BG_IMAGE_URL = ''; // Default no image +const DEFAULT_BOARD_BG_IMAGE_OPACITY = 100; // NEW const DEFAULT_MARKED_CELL_TEXT_COLOR = '#000000'; // Keep black for readability const DEFAULT_MARKED_CELL_TEXT_OPACITY = 50; const DEFAULT_MARKED_CELL_OUTLINE_COLOR = '#ffffff'; @@ -742,6 +744,7 @@ function saveBoardBgSettings() { localStorage.setItem(LS_BOARD_BG_COLOR, document.getElementById('board-bg-color-picker').value); localStorage.setItem(LS_BOARD_BG_IMAGE_URL, document.getElementById('board-bg-image-url-input').value); localStorage.setItem(LS_BOARD_BG_COLOR_OPACITY, document.getElementById('board-bg-color-opacity-slider').value); // Use new ID & key + localStorage.setItem(LS_BOARD_BG_IMAGE_OPACITY, document.getElementById('board-bg-image-opacity-slider').value); // NEW } // --- Apply board background style --- @@ -751,22 +754,19 @@ function applyBoardBgStyle() { const bgColor = localStorage.getItem(LS_BOARD_BG_COLOR) || DEFAULT_BOARD_BG_COLOR; const bgImageUrl = localStorage.getItem(LS_BOARD_BG_IMAGE_URL) || DEFAULT_BOARD_BG_IMAGE_URL; - const opacityValue = parseInt(localStorage.getItem(LS_BOARD_BG_COLOR_OPACITY) || DEFAULT_BOARD_BG_COLOR_OPACITY, 10); + const bgColorOpacity = parseInt(localStorage.getItem(LS_BOARD_BG_COLOR_OPACITY) || DEFAULT_BOARD_BG_COLOR_OPACITY, 10); + const bgImageOpacity = parseInt(localStorage.getItem(LS_BOARD_BG_IMAGE_OPACITY) || DEFAULT_BOARD_BG_IMAGE_OPACITY, 10); // NEW - // Apply opacity - REMOVED direct opacity setting - // container.style.opacity = opacityValue; + // Apply background color directly to the container + container.style.backgroundColor = hexToRgba(bgColor, bgColorOpacity); - // Apply background image or color - if (bgImageUrl) { - container.style.backgroundImage = `url('${bgImageUrl}')`; - container.style.backgroundSize = 'cover'; - container.style.backgroundPosition = 'center center'; - container.style.backgroundRepeat = 'no-repeat'; - // Apply background color with its opacity as fallback / see-through - container.style.backgroundColor = hexToRgba(bgColor, opacityValue); + // Apply background image via CSS variables for the pseudo-element + if (bgImageUrl && bgImageUrl.trim() !== '') { + container.style.setProperty('--board-bg-image-url', `url('${bgImageUrl}')`); + container.style.setProperty('--board-bg-image-opacity', bgImageOpacity / 100); } else { - container.style.backgroundImage = 'none'; - container.style.backgroundColor = hexToRgba(bgColor, opacityValue); + container.style.removeProperty('--board-bg-image-url'); + container.style.removeProperty('--board-bg-image-opacity'); } } @@ -1353,10 +1353,11 @@ function restoreCellStyleSettings(savedCellBorderColor, savedCellBorderOpacity, _restoreInputSetting('cell-outline-width-input', savedCellOutlineWidth); } -function restoreBoardBgSettings(savedBoardBgColor, savedBoardBgColorOpacity, savedBoardBgImageUrl) { +function restoreBoardBgSettings(savedBoardBgColor, savedBoardBgColorOpacity, savedBoardBgImageUrl, savedBoardBgImageOpacity) { _restoreColorPickerSetting('board-bg-color-picker', savedBoardBgColor); _restoreInputSetting('board-bg-image-url-input', savedBoardBgImageUrl); _restoreOpacitySetting('board-bg-color-opacity-slider', 'board-bg-color-opacity-value', savedBoardBgColorOpacity); + _restoreOpacitySetting('board-bg-image-opacity-slider', 'board-bg-image-opacity-value', savedBoardBgImageOpacity); // NEW applyBoardBgStyle(); // Apply loaded style } @@ -1450,6 +1451,7 @@ function loadFromLocalStorage() { const savedBoardBgColor = localStorage.getItem(LS_BOARD_BG_COLOR) || DEFAULT_BOARD_BG_COLOR; const savedBoardBgColorOpacity = localStorage.getItem(LS_BOARD_BG_COLOR_OPACITY) || DEFAULT_BOARD_BG_COLOR_OPACITY; const savedBoardBgImageUrl = localStorage.getItem(LS_BOARD_BG_IMAGE_URL) || DEFAULT_BOARD_BG_IMAGE_URL; + const savedBoardBgImageOpacity = localStorage.getItem(LS_BOARD_BG_IMAGE_OPACITY) || DEFAULT_BOARD_BG_IMAGE_OPACITY; // NEW // Restore Config Pane State loadPaneState(configIsOpen); @@ -1491,7 +1493,7 @@ function loadFromLocalStorage() { savedCellBorderWidth ); - restoreBoardBgSettings(savedBoardBgColor, savedBoardBgColorOpacity, savedBoardBgImageUrl); + restoreBoardBgSettings(savedBoardBgColor, savedBoardBgColorOpacity, savedBoardBgImageUrl, savedBoardBgImageOpacity); // Pass new value restoreSavedItems(savedDisplayedItems, savedItemsText, savedOriginalItemsText); @@ -1703,6 +1705,7 @@ document.addEventListener('DOMContentLoaded', () => { setupInputListener('board-bg-color-picker', 'input', saveBoardBgSettings, applyBoardBgStyle); setupInputListener('board-bg-image-url-input', 'input', saveBoardBgSettings, applyBoardBgStyle); setupOpacitySliderListener('board-bg-color-opacity-slider', 'board-bg-color-opacity-value', saveBoardBgSettings, applyBoardBgStyle); + setupOpacitySliderListener('board-bg-image-opacity-slider', 'board-bg-image-opacity-value', saveBoardBgSettings, applyBoardBgStyle); // NEW // --- Search Listener ---