removed queue panel slide-in animation and fixed resize flickering
This commit is contained in:
@@ -416,8 +416,9 @@ export class CoverGrid extends LitElement {
|
|||||||
* Resize-aware scroll preservation
|
* Resize-aware scroll preservation
|
||||||
*
|
*
|
||||||
* When the container width changes (e.g. queue panel
|
* When the container width changes (e.g. queue panel
|
||||||
* open/close/resize), the CSS grid reflows and the
|
* open/close, drag-resize, or window resize), the CSS
|
||||||
* absolute scroll position becomes stale.
|
* grid reflows and the absolute scroll position
|
||||||
|
* becomes stale.
|
||||||
*
|
*
|
||||||
* We compute the fractional album index at the
|
* We compute the fractional album index at the
|
||||||
* viewport center before the resize, then after the
|
* viewport center before the resize, then after the
|
||||||
@@ -440,11 +441,13 @@ export class CoverGrid extends LitElement {
|
|||||||
/**
|
/**
|
||||||
* Wire up a ResizeObserver on the scroll container.
|
* Wire up a ResizeObserver on the scroll container.
|
||||||
*
|
*
|
||||||
* Uses a debounce pattern to handle animated
|
* When the column count changes (e.g. queue panel
|
||||||
* transitions (e.g. the queue panel's 250ms width
|
* open/close), scroll position is corrected
|
||||||
* animation). The center album index is captured on
|
* synchronously in the same frame to avoid flicker.
|
||||||
* the first resize event, then restored once resizing
|
* For continuous resizes that stay within the same
|
||||||
* settles.
|
* column breakpoint (e.g. dragging the queue panel
|
||||||
|
* handle), a debounce ensures a final correction
|
||||||
|
* once resizing settles.
|
||||||
*/
|
*/
|
||||||
private setupResizeObserver() {
|
private setupResizeObserver() {
|
||||||
const container = this.scrollContainer;
|
const container = this.scrollContainer;
|
||||||
@@ -465,10 +468,34 @@ export class CoverGrid extends LitElement {
|
|||||||
this.currentColumnCount =
|
this.currentColumnCount =
|
||||||
this.getColumnCount();
|
this.getColumnCount();
|
||||||
|
|
||||||
|
/** Restore scroll so the same album stays
|
||||||
|
* at the viewport center after a reflow. */
|
||||||
|
const restoreScroll = () => {
|
||||||
|
const pending =
|
||||||
|
this.pendingCenterIndex;
|
||||||
|
|
||||||
|
this.pendingCenterIndex = null;
|
||||||
|
|
||||||
|
if (!pending) return;
|
||||||
|
|
||||||
|
const newColumns =
|
||||||
|
this.getColumnCount();
|
||||||
|
const newRow =
|
||||||
|
pending.index / newColumns;
|
||||||
|
const newCenterY =
|
||||||
|
GRID_PADDING +
|
||||||
|
newRow * rowStep;
|
||||||
|
|
||||||
|
container.scrollTop =
|
||||||
|
newCenterY -
|
||||||
|
pending.viewportHeight / 2;
|
||||||
|
|
||||||
|
this.currentColumnCount = newColumns;
|
||||||
|
};
|
||||||
|
|
||||||
this.resizeObserver = new ResizeObserver(() => {
|
this.resizeObserver = new ResizeObserver(() => {
|
||||||
// Capture on the first event using the
|
// Capture on the first event using the
|
||||||
// pre-resize column count stored before
|
// pre-resize column count.
|
||||||
// the animation started.
|
|
||||||
if (this.pendingCenterIndex === null) {
|
if (this.pendingCenterIndex === null) {
|
||||||
const centerY =
|
const centerY =
|
||||||
container.scrollTop +
|
container.scrollTop +
|
||||||
@@ -485,38 +512,31 @@ export class CoverGrid extends LitElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the debounce timer on every event
|
const newColumns = this.getColumnCount();
|
||||||
// so we wait for the animation to finish.
|
|
||||||
|
if (newColumns !== this.currentColumnCount) {
|
||||||
|
// Column count changed — correct
|
||||||
|
// scroll immediately to avoid flicker.
|
||||||
|
if (this.resizeDebounceTimer !== null) {
|
||||||
|
clearTimeout(
|
||||||
|
this.resizeDebounceTimer,
|
||||||
|
);
|
||||||
|
this.resizeDebounceTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreScroll();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same column count — debounce for a
|
||||||
|
// final adjustment once resizing settles.
|
||||||
if (this.resizeDebounceTimer !== null) {
|
if (this.resizeDebounceTimer !== null) {
|
||||||
clearTimeout(this.resizeDebounceTimer);
|
clearTimeout(this.resizeDebounceTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resizeDebounceTimer = setTimeout(
|
this.resizeDebounceTimer = setTimeout(
|
||||||
() => {
|
restoreScroll,
|
||||||
const pending =
|
|
||||||
this.pendingCenterIndex;
|
|
||||||
|
|
||||||
this.pendingCenterIndex = null;
|
|
||||||
|
|
||||||
if (!pending) return;
|
|
||||||
|
|
||||||
const newColumns =
|
|
||||||
this.getColumnCount();
|
|
||||||
const newRow =
|
|
||||||
pending.index / newColumns;
|
|
||||||
const newCenterY =
|
|
||||||
GRID_PADDING +
|
|
||||||
newRow * rowStep;
|
|
||||||
|
|
||||||
container.scrollTop =
|
|
||||||
newCenterY -
|
|
||||||
pending.viewportHeight / 2;
|
|
||||||
|
|
||||||
// Update for the next resize
|
|
||||||
// cycle.
|
|
||||||
this.currentColumnCount =
|
|
||||||
newColumns;
|
|
||||||
},
|
|
||||||
100,
|
100,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ export class QueuePanel extends LitElement {
|
|||||||
width: 0;
|
width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #212529;
|
background-color: #212529;
|
||||||
transition: width 0.25s ease-in-out;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
@@ -295,9 +294,6 @@ export class QueuePanel extends LitElement {
|
|||||||
private handleMouseDown = (e: MouseEvent) => {
|
private handleMouseDown = (e: MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.isDragging = true;
|
this.isDragging = true;
|
||||||
|
|
||||||
// Disable transition during drag for instant feedback.
|
|
||||||
this.style.transition = 'none';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private handleMouseMove = (e: MouseEvent) => {
|
private handleMouseMove = (e: MouseEvent) => {
|
||||||
@@ -318,9 +314,6 @@ export class QueuePanel extends LitElement {
|
|||||||
if (!this.isDragging) return;
|
if (!this.isDragging) return;
|
||||||
|
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
|
|
||||||
// Re-enable transition after drag ends.
|
|
||||||
this.style.removeProperty('transition');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
|
|||||||
Reference in New Issue
Block a user