// ==UserScript== // @name DuckDuckGo Images Slideshow // @namespace https://bullercodeworks.com // @version 0.4 // @description Takes a DuckDuckGo Images page and turns it into a slideshow. // @author brian@bullercodeworks.com // @match https://duckduckgo.com/* // @grant none // ==/UserScript== (function() { 'use strict'; var init = function() { lb.style.textAlign = 'center'; lb.style.height = '100%'; lb.style.width = '100%'; lb.style.position = 'fixed'; lb.style.top = '0px'; lb.style.left = '0px'; lb.style.zIndex = '99999'; lb.style.backgroundColor = 'rgba(0, 0, 0, 0.85)'; document.body.prepend(lb); lbimg.style.objectFit = 'cover'; lb.append(lbimg); imgCounter.style.backgroundColor = 'rgba(0, 0, 0, 0.85)'; imgCounter.style.color = 'white'; imgCounter.style.position = 'fixed'; imgCounter.style.top = '0px'; imgCounter.style.left = '0px'; lb.append(imgCounter); running = true; showImage(0); } var addSlideshowButton = function() { if(document.getElementById('slideshow_button') == null) { var slideshowLi = document.createElement('li'); var slideshowA = document.createElement('a'); slideshowLi.id = "slideshow_button"; slideshowLi.classList.add('zcm__item'); slideshowA.classList.add('zcm__link'); slideshowA.classList.add('js-zci-link'); slideshowA.innerText="Slideshow"; slideshowA.href='#'; slideshowLi.appendChild(slideshowA); slideshowA.onclick = init; document.getElementById('duckbar_static').appendChild(slideshowLi); } } //var allImagesCache = []; var currimg=0; var allimages = document.querySelectorAll('img.tile--img__img'); var timer; var imageTime = 5000; var running = false; var paused = false; var imgcount=allimages.length; var lb = document.createElement('div'); var lbimg = document.createElement('img'); var imgCounter = document.createElement('span'); var lastScroll = 0; var cacheimg = document.createElement('img'); var tab = document.querySelector('.js-zci-link--images'); if(tab == null) { return; } // Need that tab if(tab.classList.contains('is-active')) { addSlideshowButton(); } tab.addEventListener('click', addSlideshowButton); function updateImages() { var testimages = document.querySelectorAll('img.tile--img__img'); var testcount = testimages.length; if(testcount > imgcount) { console.log("Loading more images..."); allimages = testimages; imgcount = testcount; } } function loadDetailPaneImage(i) { var detailPanes = document.querySelectorAll('.detail__pane'); console.log(detailPanes); var detailPane = detailPanes[1]; if(detailPanes.length == 2) detailPane = detailPanes[0]; console.log(detailPane); allimages[i] = detailPane.querySelector('img.detail__media__img-highres'); } function getImageHDSource(idx) { return allimages[idx].attributes.getNamedItem('data-src').nodeValue.split("&")[0]; } function cacheImage(idx) { cacheimg.src = getImageHDSource(idx); } function showImage(idx){ if(paused){ setTimeout(()=>showImage(idx),500); return; } updateImages(); currimg = idx; if(typeof allimages[idx] == 'undefined' || allimages[idx].src == "") { timer = setTimeout(() => showImage(++idx), 100); return; } allimages[idx].click(); allimages[idx].scrollIntoView(); lbimg.src = allimages[idx].src; var useHeight=allimages[idx].height > allimages[idx].width; if(useHeight){ lbimg.style.height = '100%'; lbimg.style.width = ''; } else { lbimg.style.height = ''; lbimg.style.width = '100%' } imgCounter.innerText = "Image " + idx + " / " + imgcount; // Load HD Version setTimeout(()=>loadOrigImg(idx), 100); } function loadOrigImg(idx) { var detailPanes = document.querySelectorAll('.detail__pane'); if(detailPanes.length == 0) { console.log('No detail panes'); return; } var detailPane = detailPanes[1]; if(detailPanes.length == 2) detailPane = detailPanes[0]; var imgsrc = detailPane.querySelector('img.detail__media__img-highres').src; var newImg = new Image; newImg.onload = function() { lbimg.src = this.src; timer = setTimeout(() => showImage(++idx), imageTime); } newImg.onerror=function() { timer = setTimeout(() => showImage(++idx), imageTime); } newImg.src = imgsrc } function promptTime() { clearTimeout(timer); var resp = parseFloat(prompt("Image Time (in seconds):", imageTime/1000)); imageTime = resp * 1000; showImage(currimg); } function goto(){ clearTimeout(timer); var resp = parseInt(prompt("GOTO:", currimg)); if(resp != NaN) { doGoto(resp) } else { alert("Not a Number: "+resp) } } function doGoto(num) { updateImages(); if(num > imgcount) { if(window.scrollY == lastScroll) { alert("Looks like there aren't that many images."); return; } else { window.scrollTo(0,document.body.scrollHeight); lastScroll = window.scrollY; setTimeout(()=>doGoto(num), 2000) } } if(num != NaN) { showImage(num); } } function pause(){ if(paused){ console.log("Resuming Slideshow"); showImage(currimg); } else { console.log("Pausing Slideshow"); clearTimeout(timer); } paused = !paused; } function rewind() { console.log("Rewinding Slideshow"); clearTimeout(timer); currimg = currimg-1; showImage(currimg); } function fastforward() { console.log("Fast Forwarding Slideshow"); clearTimeout(timer); currimg = currimg+1; showImage(currimg); } document.addEventListener('keydown',(e)=>{ if(!running) { return; } var stopProp = false; switch(e.code) { case 'Space': pause(); stopProp = true; break; case 'KeyH': rewind(); stopProp = true; break; case 'KeyL': fastforward(); stopProp = true; break; case 'KeyT': promptTime(); stopProp = true; break; case 'KeyG': goto(); stopProp = true; break; case 'Escape': clearTimeout(timer); running = false; lb.remove(); stopProp = true; } if(stopProp) { e.stopPropagation(); } return stopProp; }); })();