Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<script defer src="scripts/alert-modal.js"></script>
<script defer src="scripts/wallpaper.js"></script>
<script defer src="scripts/widgets-transparency.js"></script>
<script defer src="scripts/glassmorphism.js"></script>
<script defer src="scripts/clock.js"></script>
<script defer src="scripts/weather.js"></script>
<script defer src="scripts/custom-text.js"></script>
Expand Down Expand Up @@ -1715,6 +1716,35 @@ <h1>Material You New Tab</h1>
</div>
</div>
</div>

<!-- Glassmorphism Control -->
<div class="ttcont unflex" id="glassControl">
<div class="texts">
<div class="bigText" id="glassmorphismText">Glassmorphism</div>
<div class="infoText" id="glassmorphismInfo">Enable frosted glass (backdrop blur)</div>
</div>
<label class="switch">
<input id="glassCheckbox" type="checkbox">
<span class="toggle"></span>
</label>
</div>

<div id="glassBlurControl" class="opacityBarControl">
<div class="spacer"></div>
<div class="ttcont">
<div class="texts">
<div class="bigText" id="glassBlurTitle">Blur Intensity</div>
<div class="infoText" id="glassBlurDesc">Adjust backdrop blur</div>
</div>
</div>
<div class="opacityBar">
<div class="thinLine"></div>
<div class="opacitySlider" id="glassSlider">
<div id="glassBlurLevel">8px</div>
</div>
</div>
</div>

<!-- End of opacity Bar Control -->

<!-- end of themingStuff -->
Expand Down
7 changes: 7 additions & 0 deletions locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ const en = {
// Wallpaper and settings
"uploadWallpaperText": "Upload Wallpaper", // Keep this short
"rangColor": "Pick color", // Keep this short

// Glassmorphism
"glassmorphismText": "Glassmorphism",
"glassmorphismInfo": "Enable frosted glass (backdrop blur)",
"glassBlurTitle": "Blur Intensity",
"glassBlurDesc": "Adjust backdrop blur",

"opacityTitle": "Opacity",
"adjustOpacityDesc": "Adjust interface transparency",
"backupText": "Backup",
Expand Down
150 changes: 150 additions & 0 deletions scripts/glassmorphism.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Glassmorphism feature
* Adds optional backdrop blur and supports a toggle + blur intensity slider
*/

/* =======================
DOM ELEMENTS
======================= */

const glassCheckbox = document.getElementById("glassCheckbox");
const glassBlurControl = document.getElementById("glassBlurControl");
const glassBar = document.querySelector("#glassBlurControl .opacityBar");
const glassSlider = document.getElementById("glassSlider");
const glassBlurLevel = document.getElementById("glassBlurLevel");

/* =======================
CONFIG
======================= */

const MAX_BLUR =
parseInt(
getComputedStyle(document.documentElement)
.getPropertyValue("--glass-max-blur")
) || 30;

/* =======================
CORE FUNCTIONS
======================= */

function setGlassBlur(px) {
if (!glassSlider || !glassBlurLevel) return;

const clamped = Math.max(0, Math.min(MAX_BLUR, Math.round(px)));
const percent = (clamped / MAX_BLUR) * 100;

glassSlider.style.width = `${percent}%`;
glassBlurLevel.textContent = `${clamped}px`;

document.documentElement.style.setProperty(
"--glass-blur",
`${clamped}px`
);

localStorage.setItem("glassBlur", clamped);
}

function setGlassEnabled(enabled) {
if (enabled) {
document.documentElement.classList.add("glass-enabled");
localStorage.setItem("glassEnabled", "1");

if (glassBlurControl) glassBlurControl.classList.remove("disabled");
if (glassSlider) glassSlider.setAttribute("aria-disabled", "false");
if (glassCheckbox) glassCheckbox.setAttribute("aria-checked", "true");
} else {
document.documentElement.classList.remove("glass-enabled");
localStorage.setItem("glassEnabled", "0");

if (glassBlurControl) glassBlurControl.classList.add("disabled");
if (glassSlider) glassSlider.setAttribute("aria-disabled", "true");
if (glassCheckbox) glassCheckbox.setAttribute("aria-checked", "false");
}
}

/* =======================
SLIDER DRAG HANDLING
======================= */

function handleGlassDrag(e) {
if (!glassBar) return;

const clientX = e.type.startsWith("touch")
? e.touches[0].clientX
: e.clientX;

const rect = glassBar.getBoundingClientRect();
let newPos = clientX - rect.left;

newPos = Math.max(0, Math.min(rect.width, newPos));

const percentage = (newPos / rect.width) * 100;
const px = (percentage / 100) * MAX_BLUR;

setGlassBlur(px);
}

function startGlassDrag() {
const onMove = e => handleGlassDrag(e);
const onEnd = () => {
document.removeEventListener("mousemove", onMove);
document.removeEventListener("touchmove", onMove);
document.removeEventListener("mouseup", onEnd);
document.removeEventListener("touchend", onEnd);
};

document.addEventListener("mousemove", onMove);
document.addEventListener("touchmove", onMove);
document.addEventListener("mouseup", onEnd);
document.addEventListener("touchend", onEnd);
}

/* =======================
EVENT LISTENERS
======================= */

if (glassBar) {
["mousedown", "touchstart"].forEach(evt => {
glassBar.addEventListener(
evt,
e => {
e.preventDefault();
handleGlassDrag(e);
startGlassDrag();
},
{ passive: false }
);
});
}

if (glassCheckbox) {
glassCheckbox.setAttribute("role", "switch");
glassCheckbox.setAttribute("aria-label", "Toggle glassmorphism");

glassCheckbox.addEventListener("change", () => {
setGlassEnabled(glassCheckbox.checked);
});
}

/* =======================
INIT FROM STORAGE
======================= */

const savedGlassEnabled = localStorage.getItem("glassEnabled") === "1";
const savedGlassBlur = Number(localStorage.getItem("glassBlur")) || 8;

setGlassBlur(savedGlassBlur);
setGlassEnabled(savedGlassEnabled);

if (glassCheckbox) {
glassCheckbox.checked = savedGlassEnabled;
}

/* =======================
PUBLIC API
======================= */

window.glassmorphism = {
setEnabled: setGlassEnabled,
setBlur: setGlassBlur
};
7 changes: 7 additions & 0 deletions scripts/languages.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ function applyLanguage(lang) {
"dontShowTips",
"aiSettingsIntro",
"resetAISettingsBtn",

/* Glassmorphism */
"glassmorphismText",
"glassmorphismInfo",
"glassBlurTitle",
"glassBlurDesc",

"opacityTitle",
"adjustOpacityDesc",
"footerToastTitle",
Expand Down
56 changes: 56 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
--textColorDark-blue: #1b3041;
--whitishColor-blue: #ffffff;

/* Glassmorphism variables */
--glass-blur: 0px; /* applied when glass mode is enabled */
--glass-saturation: 160%;
--glass-alpha: 0.6;
--glass-max-blur: 30px;

/* πŸ”΄πŸ”΄πŸ”΄ */
--bg-color-red: #fdbdbd;
--accentLightTint-red: #ffe7e7;
Expand Down Expand Up @@ -1867,6 +1873,56 @@ body[data-bg="wallpaper"] .humidityBar .thinLine {
font-size: 1rem;
}

html.glass-enabled .bgLightTint,
html.glass-enabled .searchbar,
html.glass-enabled .tiles,
html.glass-enabled .lrectangle,
html.glass-enabled .modal-content,
html.glass-enabled .ai-tools-list,
html.glass-enabled .bookmark-sidebar,
html.glass-enabled .liquidGlass-wrapper,
html.glass-enabled .menuBar,
html.glass-enabled .ai-modal-content
{
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
transition: background-color 200ms ease, backdrop-filter 200ms ease;
}

html.glass-enabled:not(.dark-theme) .bgLightTint {
background-color: rgba(255,255,255,var(--glass-alpha));
}

html.dark-theme.glass-enabled .bgLightTint {
background-color: rgba(0,0,0,calc(var(--glass-alpha) - 0.12));
}

.bgLightTint,
.searchbar,
.tiles,
.lrectangle,
.modal-content,
.ai-modal-content {
background-color: rgba(255, 255, 255, 0.7);
}

/* Disabled state for controls (used when glass is off) */
.opacityBarControl.disabled {
opacity: 0.55;
pointer-events: none;
filter: grayscale(0.18);
}
#glassBlurControl.disabled {
opacity: 0.55;
pointer-events: none;
filter: grayscale(0.18);
}

/* Small helper for slider when aria-disabled is true */
.opacityBar .opacitySlider[aria-disabled="true"] {
opacity: 0.6;
}

/* End of _____________________- */

/* ------------Weather Pill------------- */
Expand Down