Skip to content

Instantly share code, notes, and snippets.

@0b5vr
Last active December 17, 2025 13:42
Show Gist options
  • Select an option

  • Save 0b5vr/e73e04646cc2680a3a723f76b2d17c6a to your computer and use it in GitHub Desktop.

Select an option

Save 0b5vr/e73e04646cc2680a3a723f76b2d17c6a to your computer and use it in GitHub Desktop.
Greasemonkey/Tampermonkey pouët hover-to-thumbnail script
// ==UserScript==
// @name pouët: hover-to-thumbnail
// @description Hover a prod link to see its screenshot as a thumbnail
// @include https://www.pouet.net/*
// ==/UserScript==
const THUMB_WIDTH = 240;
const THUMB_HEIGHT = 135;
/**
* Get candidate screenshot URLs from a prod URL.
*/
function getCandScreenshotUrlsFromUrl(url) {
const match = url.match(/prod.php\?which=(\d+)$/);
if (match == null) {
return null;
}
const prodId = match[1];
return ['png', 'jpg', 'gif'].map(
(ext) => `https://content.pouet.net/screenshots/${prodId}.${ext}`
);
}
(() => {
// this div element will be shown on hover
const divThumbnail = document.createElement('divThumbnail');
divThumbnail.style.position = 'fixed';
divThumbnail.style.width = `${THUMB_WIDTH}px`;
divThumbnail.style.height = `${THUMB_HEIGHT}px`;
divThumbnail.style.background = 'black no-repeat center center / contain';
divThumbnail.style.display = 'none';
divThumbnail.style.zIndex = '10000';
divThumbnail.style.pointerEvents = 'none';
document.body.appendChild(divThumbnail);
// grab all the links to a prod
const links = document.querySelectorAll('a[href*="prod.php?which="]');
console.log(links);
// add event listeners to each link
for (let link of links) {
const urls = getCandScreenshotUrlsFromUrl(link.href);
if (urls == null) {
continue;
}
link.addEventListener('mouseenter', () => {
divThumbnail.style.display = 'block';
divThumbnail.style.backgroundImage = urls.map((url) => `url(${url})`).join(', ');
});
link.addEventListener('mouseleave', () => {
divThumbnail.style.display = 'none';
});
}
// track mouse movement to position the thumbnail element
window.addEventListener('mousemove', (event) => {
if (divThumbnail.style.display === 'none') {
return;
}
if (event.clientX + THUMB_WIDTH + 20 > window.innerWidth) {
divThumbnail.style.left = `${event.clientX - THUMB_WIDTH - 10}px`;
} else {
divThumbnail.style.left = `${event.clientX + 10}px`;
}
if (event.clientY + THUMB_HEIGHT + 20 > window.innerHeight) {
divThumbnail.style.top = `${event.clientY - THUMB_HEIGHT - 10}px`;
} else {
divThumbnail.style.top = `${event.clientY + 10}px`;
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment