Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name ArchDaily Image Gallery (Adaptive)
- // @namespace http://tampermonkey.net/
- // @version 1.2
- // @description Replace page with adaptive image gallery from figure imgs (ArchDaily)
- // @author You
- // @match https://www.archdaily.com/*/*
- // @grant none
- // @run-at document-end
- // ==/UserScript==
- // https://www.archdaily.com/1037995/kulhad-pavilion-wallmakers
- // const text = [...document.querySelectorAll('article p')].map(p=>p.innerText).filter(t=>t.length>10).join();
- // const images= [...document.querySelectorAll('.gallery-thumbs li a')].map(a=>a.href)
- (function() {
- 'use strict';
- // Wait for page to fully load
- function initGallery() {
- // Auto-detect images from ArchDaily figure imgs or global images array
- const title = document.querySelector('h1').innerText;
- const text = [...document.querySelectorAll('article p')].map(p=>p.innerText).filter(t=>t.length>10).join();
- let sources = [...document.querySelectorAll('.gallery-thumbs-link picture img')].map(i=>i.src).filter(s=>s).map(s=>s.replace('medium_jpg', 'slideshow'));
- let images = sources;
- // Final dedupe and validation
- /*
- images = images.filter((src, index, self) =>
- src && src.trim && src.trim() !== '' && self.indexOf(src) === index
- );
- */
- if (!images.length) {
- console.log('No valid images found, retrying...');
- return false; // Not ready yet
- }
- // Determine optimal layout based on image count
- const count = images.length;
- let gridConfig = {
- columns: 'repeat(auto-fit, minmax(250px, 1fr))',
- minSize: '250px',
- gap: '15px',
- height: '200px'
- };
- if (count === 1) {
- gridConfig = {
- columns: '1fr',
- minSize: '100%',
- gap: '0',
- height: 'auto',
- maxHeight: '80vh'
- };
- } else if (count === 2) {
- gridConfig = {
- columns: 'repeat(2, 1fr)',
- minSize: '300px',
- gap: '20px',
- height: '400px'
- };
- } else if (count <= 4) {
- gridConfig = {
- columns: 'repeat(2, 1fr)',
- minSize: '300px',
- gap: '15px',
- height: '300px'
- };
- } else if (count <= 6) {
- gridConfig = {
- columns: 'repeat(3, 1fr)',
- minSize: '280px',
- gap: '15px',
- height: '250px'
- };
- } else if (count <= 12) {
- gridConfig = {
- columns: 'repeat(auto-fit, minmax(300px, 1fr))',
- minSize: '300px',
- gap: '15px',
- height: '220px'
- };
- }
- // Replace entire page content
- document.documentElement.innerHTML = `
- <!DOCTYPE html>
- <html>
- <head>
- <style>
- * { box-sizing: border-box; }
- body {
- margin: 0; padding: 20px;
- font-family: Arial, sans-serif;
- background: #222; color: white;
- }
- .gallery {
- display: grid;
- grid-template-columns: ${gridConfig.columns};
- gap: ${gridConfig.gap};
- max-width: 1400px;
- margin: 0 auto;
- }
- .gallery img {
- width: 100%;
- height: ${gridConfig.height};
- ${gridConfig.maxHeight ? 'max-height: ' + gridConfig.maxHeight + ';' : ''}
- object-fit: cover;
- border-radius: 8px;
- cursor: pointer;
- box-shadow: 0 4px 12px rgba(0,0,0,0.5);
- transition: transform 0.3s ease;
- }
- .gallery img:hover { transform: scale(1.02); }
- .info-bar {
- font-size: 120%;
- text-align: left;
- margin-bottom: 20px;
- padding: 2em;
- background: rgba(255,255,255,0.1);
- color: #ccc;
- border-radius: 8px;
- max-width: 1400px;
- margin: 0 auto 20px;
- }
- h1 {
- text-align : center;key
- }
- .modal {
- display: none;
- position: fixed;
- top: 0; left: 0;
- width: 100%; height: 100%;
- background: rgba(0,0,0,0.95);
- z-index: 9999;
- }
- .modal img {
- max-width: 90%;
- max-height: 90%;
- position: absolute;
- top: 50%; left: 50%;
- transform: translate(-50%, -50%);
- border-radius: 8px;
- }
- .close {
- position: absolute;
- top: 20px; right: 30px;
- color: white;
- font-size: 40px;
- font-weight: bold;
- cursor: pointer;
- }
- .nav-btn {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- background: rgba(255,255,255,0.2);
- border: none;
- color: white;
- font-size: 24px;
- padding: 15px 20px;
- cursor: pointer;
- border-radius: 50%;
- width: 60px;
- height: 60px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: background 0.3s;
- }
- .nav-btn:hover { background: rgba(255,255,255,0.4); }
- .prev { left: 30px; }
- .next { right: 30px; }
- .counter {
- position: absolute;
- bottom: 30px;
- left: 50%;
- transform: translateX(-50%);
- background: rgba(0,0,0,0.7);
- padding: 10px 20px;
- border-radius: 20px;
- font-size: 18px;
- }
- @media (max-width: 768px) {
- .gallery {
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) !important;
- }
- .gallery img {
- height: 150px !important;
- }
- }
- </style>
- </head>
- <body>
- <div class="info-bar">
- <h1>${title}</h1>
- <i>${text}</i>
- </div>
- <div class="gallery"></div>
- <div class="modal">
- <span class="close">×</span>
- <img id="modalImg">
- <button class="nav-btn prev">‹</button>
- <button class="nav-btn next">›</button>
- <div class="counter" id="counter"></div>
- </div>
- </body>
- </html>`;
- // Elements
- const gallery = document.querySelector('.gallery');
- const modal = document.querySelector('.modal');
- const modalImg = document.getElementById('modalImg');
- const closeBtn = document.querySelector('.close');
- const prevBtn = document.querySelector('.prev');
- const nextBtn = document.querySelector('.next');
- const counter = document.getElementById('counter');
- let currentIndex = 0;
- const imageSources = images; // Store reference
- // Build gallery
- images.forEach((src, i) => {
- const img = document.createElement('img');
- img.src = src;
- img.alt = `Image ${i + 1}`;
- img.onclick = () => openModal(i);
- gallery.appendChild(img);
- });
- // Modal controls
- function openModal(index) {
- currentIndex = index;
- modal.style.display = 'block';
- modalImg.src = imageSources[currentIndex];
- updateCounter();
- }
- function updateCounter() {
- counter.textContent = `${currentIndex + 1} / ${imageSources.length}`;
- }
- function showPrev() {
- currentIndex = (currentIndex - 1 + imageSources.length) % imageSources.length;
- modalImg.src = imageSources[currentIndex];
- updateCounter();
- }
- function showNext() {
- currentIndex = (currentIndex + 1) % imageSources.length;
- modalImg.src = imageSources[currentIndex];
- updateCounter();
- }
- closeBtn.onclick = () => modal.style.display = 'none';
- prevBtn.onclick = showPrev;
- nextBtn.onclick = showNext;
- modal.onclick = e => { if (e.target === modal) modal.style.display = 'none'; };
- document.addEventListener('keydown', function(e) {
- if (modal.style.display === 'block') {
- if (e.key === 'ArrowLeft') showPrev();
- if (e.key === 'ArrowRight') showNext();
- if (e.key === 'Escape') modal.style.display = 'none';
- }
- }, true);
- return true; // Success
- }
- // Wait for full load with retries
- function waitForLoad() {
- if (document.readyState === 'complete' || document.readyState === 'interactive') {
- const maxAttempts = 5; // 5 seconds
- let attempts = 0;
- function tryInit() {
- try {
- attempts++;
- if (initGallery() || attempts >= maxAttempts) {
- if (attempts >= maxAttempts) {
- alert('Gallery failed to initialize - page might not have images');
- }
- return;
- }
- setTimeout(tryInit, 100);
- } catch (e) {
- console.error('*********** ', e);
- alert('Error.', e);
- }
- }
- tryInit();
- } else {
- setTimeout(waitForLoad, 100);
- }
- }
- // Start waiting
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', waitForLoad);
- window.addEventListener('load', waitForLoad);
- } else {
- waitForLoad();
- }
- })();
Advertisement
Add Comment
Please, Sign In to add comment