Skip to content

Commit

Permalink
feat(ambient-mode): support ambient mode on Song section
Browse files Browse the repository at this point in the history
resolve #1555
  • Loading branch information
Su-Yong committed Dec 29, 2023
1 parent f46c431 commit f0f5d9d
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
79 changes: 77 additions & 2 deletions src/plugins/ambient-mode/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,73 @@ export default createPlugin({
observer: null as MutationObserver | null,

start() {
const injectBlurImage = () => {
const songImage = document.querySelector<HTMLImageElement>(
'#song-image',
);
const image = document.querySelector<HTMLImageElement>(
'#song-image yt-img-shadow > img',
);

if (!songImage) return null;
if (!image) return null;

const blurImage = document.createElement('img');
blurImage.classList.add('html5-blur-image');
blurImage.src = image.src;

const applyImageAttribute = () => {
const rect = image.getBoundingClientRect();

const newWidth = Math.floor(image.width || rect.width);
const newHeight = Math.floor(image.height || rect.height);

if (newWidth === 0 || newHeight === 0) return;

if (this.isFullscreen) blurImage.classList.add('fullscreen');
else blurImage.classList.remove('fullscreen');

const leftOffset = (newWidth * (this.sizeRatio - 1)) / 2;
const topOffset = (newHeight * (this.sizeRatio - 1)) / 2;
blurImage.style.setProperty('--left', `${-1 * leftOffset}px`);
blurImage.style.setProperty('--top', `${-1 * topOffset}px`);
blurImage.style.setProperty('--width', `${newWidth * this.sizeRatio}px`);
blurImage.style.setProperty('--height', `${newHeight * this.sizeRatio}px`);
blurImage.style.setProperty('--blur', `${this.blur}px`);
blurImage.style.setProperty('--opacity', `${this.opacity}`);
};

this.update = applyImageAttribute;

const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
applyImageAttribute();
}
});
});
const resizeObserver = new ResizeObserver(() => {
applyImageAttribute();
});

applyImageAttribute();
observer.observe(songImage, { attributes: true });
resizeObserver.observe(songImage);
window.addEventListener('resize', applyImageAttribute);

/* injecting */
songImage.prepend(blurImage);

/* cleanup */
return () => {
observer.disconnect();
resizeObserver.disconnect();
window.removeEventListener('resize', applyImageAttribute);

if (blurImage.isConnected) blurImage.remove();
};
};

const injectBlurVideo = (): (() => void) | null => {
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
const video = document.querySelector<HTMLVideoElement>(
Expand Down Expand Up @@ -280,13 +347,21 @@ export default createPlugin({
};
};

const isVideoMode = () => {
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
if (!songVideo) return false;
console.log(getComputedStyle(songVideo).display);

return getComputedStyle(songVideo).display !== 'none';
};

const playerPage = document.querySelector<HTMLElement>('#player-page');
const ytmusicAppLayout = document.querySelector<HTMLElement>('#layout');

const isPageOpen = ytmusicAppLayout?.hasAttribute('player-page-open');
if (isPageOpen) {
this.unregister?.();
this.unregister = injectBlurVideo() ?? null;
this.unregister = (isVideoMode() ? injectBlurVideo() : injectBlurImage()) ?? null;
}

const observer = new MutationObserver((mutationsList) => {
Expand All @@ -296,7 +371,7 @@ export default createPlugin({
ytmusicAppLayout?.hasAttribute('player-page-open');
if (isPageOpen) {
this.unregister?.();
this.unregister = injectBlurVideo() ?? null;
this.unregister = (isVideoMode() ? injectBlurVideo() : injectBlurImage()) ?? null;
} else {
this.unregister?.();
this.unregister = null;
Expand Down
14 changes: 14 additions & 0 deletions src/plugins/ambient-mode/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,17 @@
#song-video .html5-video-container > video {
top: 0 !important;
}

#song-image .html5-blur-image {
position: absolute;

left: var(--left, 0px);
top: var(--top, 0px);
width: var(--width, 100%) !important;
height: var(--height, 100%) !important;

filter: blur(var(--blur, 100px));
opacity: var(--opacity, 1);

pointer-events: none;
}

0 comments on commit f0f5d9d

Please sign in to comment.