PerfectGonzo: View Photos Popup & Carousel (High Res, Fit Entire Image, Grid Toggle)

Adds a button that opens a fullscreen grid of high-res photos. Clicking a photo opens a carousel overlay that scales the image to fit without cropping. In the carousel, a "Grid View" button lets you return to the grid.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         PerfectGonzo: View Photos Popup & Carousel (High Res, Fit Entire Image, Grid Toggle)
// @namespace    http://tampermonkey.net/
// @version      1.7
// @description  Adds a button that opens a fullscreen grid of high-res photos. Clicking a photo opens a carousel overlay that scales the image to fit without cropping. In the carousel, a "Grid View" button lets you return to the grid.
// @match        *://*.perfectgonzo.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Function to create the grid popup gallery
    function createPopupGallery(imageUrls) {
        // Create overlay for grid gallery
        const overlay = document.createElement('div');
        overlay.id = 'pgPhotoOverlay';
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
        overlay.style.zIndex = '10000';
        overlay.style.overflowY = 'auto';
        overlay.style.padding = '20px';

        // Close button for grid gallery
        const closeBtn = document.createElement('button');
        closeBtn.innerText = 'X';
        closeBtn.style.position = 'fixed';
        closeBtn.style.top = '20px';
        closeBtn.style.right = '20px';
        closeBtn.style.fontSize = '24px';
        closeBtn.style.background = 'transparent';
        closeBtn.style.color = '#fff';
        closeBtn.style.border = 'none';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.zIndex = '10001';
        overlay.appendChild(closeBtn);

        closeBtn.addEventListener('click', function() {
            document.body.removeChild(overlay);
        });

        // Gallery container (grid layout)
        const galleryContainer = document.createElement('div');
        galleryContainer.style.display = 'flex';
        galleryContainer.style.flexWrap = 'wrap';
        galleryContainer.style.justifyContent = 'center';
        galleryContainer.style.gap = '20px';
        galleryContainer.style.marginTop = '60px'; // leave room for the close button
        overlay.appendChild(galleryContainer);

        imageUrls.forEach((url, index) => {
            const imgContainer = document.createElement('div');
            imgContainer.style.flex = '1 1 auto';
            imgContainer.style.maxWidth = '400px';
            imgContainer.style.cursor = 'pointer';

            const img = document.createElement('img');
            img.src = url;
            img.alt = 'Photo';
            img.style.width = '100%';
            img.style.height = 'auto';
            img.style.border = '2px solid #fff';
            img.style.boxShadow = '0 0 10px rgba(255,255,255,0.5)';
            img.style.transition = 'transform 0.2s ease-in-out';
            img.addEventListener('mouseover', () => { img.style.transform = 'scale(1.05)'; });
            img.addEventListener('mouseout', () => { img.style.transform = 'scale(1)'; });

            // When clicking the image, close the grid and open the carousel at this index.
            img.addEventListener('click', function(e) {
                e.stopPropagation();
                document.body.removeChild(overlay);
                createCarousel(index, imageUrls);
            });

            imgContainer.appendChild(img);
            galleryContainer.appendChild(imgContainer);
        });

        document.body.appendChild(overlay);
    }

    // Function to create a fullscreen carousel overlay with a "Grid View" button
    function createCarousel(currentIndex, imageUrls) {
        // Create carousel overlay
        const carouselOverlay = document.createElement('div');
        carouselOverlay.id = 'pgCarouselOverlay';
        carouselOverlay.style.position = 'fixed';
        carouselOverlay.style.top = '0';
        carouselOverlay.style.left = '0';
        carouselOverlay.style.width = '100vw';
        carouselOverlay.style.height = '100vh';
        carouselOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
        carouselOverlay.style.zIndex = '10001';
        carouselOverlay.style.display = 'flex';
        carouselOverlay.style.alignItems = 'center';
        carouselOverlay.style.justifyContent = 'center';

        // Container for image and controls
        const container = document.createElement('div');
        container.style.position = 'relative';
        container.style.width = '100vw';
        container.style.height = '100vh';
        container.style.display = 'flex';
        container.style.alignItems = 'center';
        container.style.justifyContent = 'center';
        carouselOverlay.appendChild(container);

        // Image element with scaling that preserves aspect ratio
        const carouselImg = document.createElement('img');
        carouselImg.src = imageUrls[currentIndex];
        carouselImg.style.display = 'block';
        carouselImg.style.maxWidth = '100%';
        carouselImg.style.maxHeight = '100%';
        carouselImg.style.width = 'auto';
        carouselImg.style.height = 'auto';
        carouselImg.style.objectFit = 'contain';
        container.appendChild(carouselImg);

        // Left arrow
        const leftArrow = document.createElement('div');
        leftArrow.innerHTML = '❮'; // left arrow symbol
        leftArrow.style.position = 'absolute';
        leftArrow.style.left = '20px';
        leftArrow.style.top = '50%';
        leftArrow.style.transform = 'translateY(-50%)';
        leftArrow.style.fontSize = '48px';
        leftArrow.style.color = '#fff';
        leftArrow.style.cursor = 'pointer';
        leftArrow.style.userSelect = 'none';
        container.appendChild(leftArrow);

        // Right arrow
        const rightArrow = document.createElement('div');
        rightArrow.innerHTML = '❯'; // right arrow symbol
        rightArrow.style.position = 'absolute';
        rightArrow.style.right = '20px';
        rightArrow.style.top = '50%';
        rightArrow.style.transform = 'translateY(-50%)';
        rightArrow.style.fontSize = '48px';
        rightArrow.style.color = '#fff';
        rightArrow.style.cursor = 'pointer';
        rightArrow.style.userSelect = 'none';
        container.appendChild(rightArrow);

        // Close button
        const closeBtn = document.createElement('div');
        closeBtn.innerHTML = '×';
        closeBtn.style.position = 'absolute';
        closeBtn.style.top = '20px';
        closeBtn.style.right = '30px';
        closeBtn.style.fontSize = '48px';
        closeBtn.style.color = '#fff';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.userSelect = 'none';
        container.appendChild(closeBtn);

        // New: "Grid View" button to go back to grid overlay.
        const gridViewBtn = document.createElement('button');
        gridViewBtn.innerText = 'Grid View';
        gridViewBtn.style.position = 'absolute';
        gridViewBtn.style.top = '20px';
        gridViewBtn.style.left = '30px';
        gridViewBtn.style.fontSize = '16px';
        gridViewBtn.style.padding = '8px 12px';
        gridViewBtn.style.background = '#ffa700';
        gridViewBtn.style.border = 'none';
        gridViewBtn.style.borderRadius = '5px';
        gridViewBtn.style.cursor = 'pointer';
        gridViewBtn.style.zIndex = '10002';
        container.appendChild(gridViewBtn);

        // Arrow navigation events
        leftArrow.addEventListener('click', function(e) {
            e.stopPropagation();
            currentIndex = (currentIndex - 1 + imageUrls.length) % imageUrls.length;
            carouselImg.src = imageUrls[currentIndex];
        });

        rightArrow.addEventListener('click', function(e) {
            e.stopPropagation();
            currentIndex = (currentIndex + 1) % imageUrls.length;
            carouselImg.src = imageUrls[currentIndex];
        });

        // Close carousel events
        closeBtn.addEventListener('click', function() {
            document.body.removeChild(carouselOverlay);
        });
        carouselOverlay.addEventListener('click', function(e) {
            if (e.target === carouselOverlay) {
                document.body.removeChild(carouselOverlay);
            }
        });

        // "Grid View" button: remove carousel and reopen grid overlay
        gridViewBtn.addEventListener('click', function(e) {
            e.stopPropagation();
            document.body.removeChild(carouselOverlay);
            createPopupGallery(imageUrls);
        });

        document.body.appendChild(carouselOverlay);
    }

    // When the page loads, add the "View Photos" button
    window.addEventListener('load', function() {
        const btn = document.createElement('button');
        btn.innerText = 'View Photos';
        btn.style.position = 'fixed';
        btn.style.top = '10px';
        btn.style.right = '10px';
        btn.style.zIndex = '9999';
        btn.style.padding = '10px 15px';
        btn.style.background = '#ffa700';
        btn.style.border = 'none';
        btn.style.borderRadius = '5px';
        btn.style.cursor = 'pointer';
        btn.style.fontSize = '14px';
        document.body.appendChild(btn);

        // On button click, gather high-res photo URLs from the Photos section
        btn.addEventListener('click', function() {
            let imageUrls = [];
            const photoAnchors = document.querySelectorAll('.bxslider_pics_fancybox a[href]');
            photoAnchors.forEach(anchor => {
                const url = anchor.href;
                if(url) {
                    imageUrls.push(url);
                }
            });
            imageUrls = [...new Set(imageUrls)]; // Remove duplicates
            if(imageUrls.length > 0) {
                createPopupGallery(imageUrls);
            } else {
                alert('No photos found.');
            }
        });
    });
})();