Enhance gradient generator UI with improved layout and styling adjustments

This commit is contained in:
mr. M
2025-02-20 19:48:45 +01:00
parent 48ab77ef52
commit b71903e04b
4 changed files with 194 additions and 36 deletions

View File

@@ -117,8 +117,7 @@
<label data-l10n-id="zen-panel-ui-gradient-generator-opacity-text"></label>
<html:input type="range" min="0" max="1" value="0.5" step="0.05" oninput="gZenThemePicker.onOpacityChange(event);" id="PanelUI-zen-gradient-generator-opacity" />
</vbox>
<vbox>
<html:input type="range" min="0" max="1" value="0.5" step="0.05" oninput="gZenThemePicker.onTextureChange(event);" id="PanelUI-zen-gradient-generator-texture" />
<vbox id="PanelUI-zen-gradient-generator-texture-wrapper">
</vbox>
</hbox>
</hbox>

View File

@@ -60,7 +60,11 @@
font-weight: 600;
}
gap: 10px;
display: flex;
justify-content: space-between;
width: 100%;
margin-bottom: 10px;
align-items: center;
}
#PanelUI-zen-gradient-generator-predefined {
@@ -135,14 +139,16 @@
#PanelUI-zen-gradient-generator-opacity,
#PanelUI-zen-gradient-generator-texture {
margin: 0 !important;
margin-top: 5px !important;
background: transparent;
&::-moz-range-thumb {
background: var(--zen-colors-tertiary);
border: 2px solid var(--zen-colors-border);
border-radius: 50%;
height: 13px;
border-radius: 12px;
height: 25px;
width: 13px;
cursor: pointer;
}
&::-moz-range-track {
@@ -154,7 +160,7 @@
&::-moz-range-progress {
background: var(--zen-primary-color);
border-radius: 999px;
height: 6px;
height: 8px;
}
}
@@ -168,15 +174,15 @@
margin-bottom: 20px;
background: var(--zen-toolbar-element-bg);
background-image: radial-gradient(light-dark(rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.225)) 1px, transparent 0);
background-image: radial-gradient(light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.4)) 1px, transparent 0);
background-position: -19px -19px;
background-size: 10px 10px;
background-size: 5px 5px;
& .zen-theme-picker-dot {
position: absolute;
z-index: 2;
width: 22px;
height: 22px;
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--zen-theme-picker-dot-color);
@media (-prefers-color-scheme: dark) {
@@ -185,13 +191,17 @@
cursor: pointer;
border: 2px solid #ffffff;
animation: zen-theme-picker-dot-animation 0.5s;
transition: transform 0.2s;
transform: translate(-50%, -50%);
&:first-of-type {
width: 28px;
height: 28px;
width: 30px;
height: 30px;
border-width: 3px;
z-index: 2;
transition: transform 0.1s;
&:hover {
transform: scale(1.05) translate(-50%, -50%);
}
}
&[dragging='true'] {
@@ -222,7 +232,7 @@
z-index: 1;
transform: translateX(-50%);
& .separator,
& button {
& #PanelUI-zen-gradient-generator-color-toggle-algo {
background: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1));
}
@@ -263,3 +273,69 @@
display: none !important;
}
}
#PanelUI-zen-gradient-generator-texture-wrapper {
width: 4rem;
height: 4rem;
position: relative;
&::after {
content: '';
position: absolute;
width: 2.7rem;
height: 2.7rem;
border: 1px solid color-mix(in srgb, var(--zen-colors-border) 50%, transparent 50%);
border-radius: 50%;
/* 3d effect */
background: linear-gradient(-45deg, transparent -10%, light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1)) 110%);
z-index: 2;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
}
&::before {
background-image: url(chrome://browser/content/zen-images/grain-bg.png);
opacity: var(--zen-grainy-background-opacity, 0);
mix-blend-mode: hard-light;
width: 2.7rem;
height: 2.7rem;
pointer-events: none;
top: 50%;
border-radius: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
content: '';
position: absolute;
}
& .zen-theme-picker-texture-dot {
height: 4px;
width: 4px;
border-radius: 50%;
background: light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
position: absolute;
transition: opacity 0.2s;
transform: translate(-50%, -50%);
pointer-events: none;
&:not(.active) {
opacity: 0.2;
}
}
& #PanelUI-zen-gradient-generator-texture-handler {
width: 6px;
height: 12px;
background: light-dark(#757575, #d1d1d1);
position: absolute;
transition: height 0.1s;
z-index: 2;
border-radius: 2px;
cursor: pointer;
&:hover {
height: 14px;
}
}
}

View File

@@ -31,7 +31,7 @@
border-radius: var(--border-radius-medium);
outline: none !important;
border: none !important;
border: 1px solid hsla(0, 0%, 100%, 0.1) !important;
margin: 1px;
box-shadow: none !important;
@@ -113,12 +113,7 @@
}
#urlbar[breakout-extend='true'] #urlbar-background {
box-shadow:
inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.1),
/* 2. shadow ring 👇 */ 0 0 0 1px hsla(230, 13%, 9%, 0.075),
/* 3. multiple soft shadows 👇 */ 0 0.3px 0.4px hsla(230, 13%, 9%, 0.02),
0 0.9px 1.5px hsla(230, 13%, 9%, 0.045),
0 6.5px 12px hsla(230, 13%, 9%, 0.1) !important;
box-shadow: 0px 0px 90px -10px rgba(0, 0, 0, 0.6) !important;
backdrop-filter: none !important;
}
@@ -393,7 +388,10 @@ button.popup-notification-dropmarker {
/* We cant have a transparent background with a backdrop-filter because on normal websites,
the backdrop woudn't work, we would need to apply a clip-path to the site and that's not recommended
due to performance issues */
background-color: light-dark(hsl(0, 0%, 100%), hsl(0, 0%, 14%)) !important;
background-color: light-dark(
hsl(0, 0%, 100%),
color-mix(in srgb, hsl(0, 0%, 5%) 90%, var(--zen-colors-primary) 10%)
) !important;
@media (-prefers-color-scheme: dark) {
outline: 1px solid rgba(0, 0, 0, 0.3) !important;
}
@@ -412,11 +410,12 @@ button.popup-notification-dropmarker {
#urlbar[open][zen-floating-urlbar='true'] {
z-index: 1000;
max-width: 45vw;
min-width: 45vw !important;
max-width: unset;
min-width: unset !important;
--urlbar-container-height: 55px !important;
--urlbar-margin-inline: 10px !important;
position: fixed;
width: min(90%, 45rem) !important;
font-size: 1.15em !important;
@media (-moz-platform: macos) {

View File

@@ -33,6 +33,7 @@
this.initCanvas();
this.initCustomColorInput();
this.initTextureInput();
window.matchMedia('(prefers-color-scheme: dark)').addListener(this.onDarkModeChange.bind(this));
}
@@ -141,6 +142,67 @@
this.customColorInput.addEventListener('keydown', this.onCustomColorKeydown.bind(this));
}
initTextureInput() {
const wrapper = document.getElementById('PanelUI-zen-gradient-generator-texture-wrapper');
const wrapperWidth = wrapper.getBoundingClientRect().width;
// Add elements in a circular pattern, where the center is the center of the wrapper
for (let i = 0; i < 16; i++) {
const dot = document.createElement('div');
dot.classList.add('zen-theme-picker-texture-dot');
const position = (i / 16) * Math.PI * 2 + wrapperWidth;
dot.style.left = `${Math.cos(position) * 50 + 50}%`;
dot.style.top = `${Math.sin(position) * 50 + 50}%`;
wrapper.appendChild(dot);
}
this._textureHandler = document.createElement('div');
this._textureHandler.id = 'PanelUI-zen-gradient-generator-texture-handler';
this._textureHandler.addEventListener('mousedown', this.onTextureHandlerMouseDown.bind(this));
wrapper.appendChild(this._textureHandler);
}
onTextureHandlerMouseDown(event) {
event.preventDefault();
this._onTextureMouseMove = this.onTextureMouseMove.bind(this);
this._onTextureMouseUp = this.onTextureMouseUp.bind(this);
document.addEventListener('mousemove', this._onTextureMouseMove);
document.addEventListener('mouseup', this._onTextureMouseUp);
}
onTextureMouseMove(event) {
event.preventDefault();
const wrapper = document.getElementById('PanelUI-zen-gradient-generator-texture-wrapper');
const wrapperRect = wrapper.getBoundingClientRect();
// Determine how much rotation there is based on the mouse position and the center of the wrapper
const rotation = Math.atan2(
event.clientY - wrapperRect.top - wrapperRect.height / 2,
event.clientX - wrapperRect.left - wrapperRect.width / 2
);
const previousTexture = this.currentTexture;
this.currentTexture = (rotation * 180) / Math.PI + 90;
// if it's negative, add 360 to make it positive
if (this.currentTexture < 0) {
this.currentTexture += 360;
}
// make it go from 1 to 0 instead of being in degrees
this.currentTexture /= 360;
// We clip it to the closest button out of 16 possible buttons
this.currentTexture = Math.round(this.currentTexture * 16) / 16;
if (this.currentTexture === 1) {
this.currentTexture = 0;
}
if (previousTexture !== this.currentTexture) {
this.updateCurrentWorkspace();
}
}
onTextureMouseUp(event) {
event.preventDefault();
document.removeEventListener('mousemove', this._onTextureMouseMove);
document.removeEventListener('mouseup', this._onTextureMouseUp);
this._onTextureMouseMove = null;
this._onTextureMouseUp = null;
}
onCustomColorKeydown(event) {
// Check for Enter key to add custom colors
if (event.key === 'Enter') {
@@ -381,7 +443,7 @@
const dotPad = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = dotPad.getBoundingClientRect();
const padding = 90;
const padding = 20;
let updatedDots = [...dots];
const centerPosition = { x: rect.width / 2, y: rect.height / 2 };
@@ -554,7 +616,7 @@
const gradient = this.panel.querySelector('.zen-theme-picker-gradient');
const rect = gradient.getBoundingClientRect();
const padding = 90;
const padding = 20;
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
@@ -688,7 +750,7 @@
if (this.dragging) {
event.preventDefault();
const rect = this.panel.querySelector('.zen-theme-picker-gradient').getBoundingClientRect();
const padding = 90; // each side
const padding = 20; // each side
// do NOT let the ball be draged outside of an imaginary circle. You can drag it anywhere inside the circle
// if the distance between the center of the circle and the dragged ball is bigger than the radius, then the ball
// should be placed on the edge of the circle. If it's inside the circle, then the ball just follows the mouse
@@ -741,11 +803,6 @@
this.updateCurrentWorkspace();
}
onTextureChange(event) {
this.currentTexture = event.target.value;
this.updateCurrentWorkspace();
}
getToolbarModifiedBase() {
return this.isDarkMode
? 'color-mix(in srgb, var(--zen-themed-toolbar-bg) 80%, #fff 20%)'
@@ -783,8 +840,7 @@
}
//TODO: add a better noise system that adds noise not just changes transparency
updateNoise(texture) {
const wrapper = document.getElementById('zen-main-app-wrapper');
wrapper.style.setProperty('--zen-grainy-background-opacity', texture);
document.documentElement.style.setProperty('--zen-grainy-background-opacity', texture);
}
hexToRgb(hex) {
@@ -941,8 +997,33 @@
browser.document.getElementById('PanelUI-zen-gradient-generator-opacity').value =
browser.gZenThemePicker.currentOpacity;
browser.document.getElementById('PanelUI-zen-gradient-generator-texture').value =
browser.gZenThemePicker.currentTexture;
const textureSelectWrapper = browser.document.getElementById('PanelUI-zen-gradient-generator-texture-wrapper');
const textureWrapperWidth = textureSelectWrapper.getBoundingClientRect().width;
// Dont show when hidden
if (textureWrapperWidth) {
// rotate and trasnform relative to the wrapper width depending on the texture value
const textureValue = this.currentTexture;
const textureHandler = browser.gZenThemePicker._textureHandler;
const rotation = textureValue * 360 - 90;
textureHandler.style.transform = `rotate(${rotation + 90}deg)`;
// add top and left to center the texture handler in relation with textureWrapperWidth
// based on the rotation
const top = Math.sin((rotation * Math.PI) / 180) * (textureWrapperWidth / 2) - 6;
const left = Math.cos((rotation * Math.PI) / 180) * (textureWrapperWidth / 2) - 3;
textureHandler.style.top = `${textureWrapperWidth / 2 + top}px`;
textureHandler.style.left = `${textureWrapperWidth / 2 + left}px`;
// Highlight the 16 buttons based on the texture value
const buttons = browser.document.querySelectorAll('.zen-theme-picker-texture-dot');
let i = 4;
for (const button of buttons) {
button.classList.toggle('active', i / 16 <= textureValue);
i++;
// We start at point 4 because that's the first point that is not in the middle of the texture
if (i === 16) {
i = 0;
}
}
}
const gradient = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors);
const gradientToolbar = browser.gZenThemePicker.getGradient(workspaceTheme.gradientColors, true);
@@ -1070,6 +1151,9 @@
handlePanelOpen() {
this.initThemePicker();
setTimeout(() => {
this.updateCurrentWorkspace();
}, 200);
}
}