// ==UserScript== // @name Twitter Enlarge the image in the media section // @name:ja Twitter メディア欄で画像を拡大するやつ // @namespace http://tampermonkey.net/ // @version 1.01 // @description Enlarge the image in the media section to view the entire image // @description:ja メディア欄の画像を拡大して全体表示します。 // @author Nogaccho // @match https://twitter.com/* // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; let previewDiv = null; let lastHoveredImage = null; function createPreviewDiv() { if (previewDiv === null) { previewDiv = document.createElement('div'); document.body.appendChild(previewDiv); previewDiv.style.position = 'fixed'; previewDiv.style.zIndex = '1000'; previewDiv.style.pointerEvents = 'none'; previewDiv.style.display = 'none'; previewDiv.style.top = '50%'; previewDiv.style.left = '50%'; previewDiv.style.transform = 'translate(-50%, -50%)'; } } function addEventListeners() { document.addEventListener('mouseover', onMouseOver); document.addEventListener('mouseout', onMouseOut); } function removeEventListeners() { document.removeEventListener('mouseover', onMouseOver); document.removeEventListener('mouseout', onMouseOut); } function onMouseOver(event) { const target = event.target; if (target.tagName === 'IMG' && target.src && target.src.includes('twimg.com')) { // 画像URLを修正して高解像度のバージョンを取得 const highResImageUrl = target.src.split('?')[0] + '?format=jpg&name=medium'; const img = new Image(); img.onload = function() { const aspectRatio = img.width / img.height; if (aspectRatio < 2.5 || aspectRatio > 3.5) { if (lastHoveredImage !== target) { lastHoveredImage = target; const previewImg = document.createElement('img'); previewImg.src = highResImageUrl; // 高解像度の画像URLを使用 previewImg.style.maxWidth = 'calc(100vw - 500px)'; previewImg.style.maxHeight = 'calc(100vh - 50px)'; previewImg.style.objectFit = 'contain'; previewDiv.innerHTML = ''; previewDiv.appendChild(previewImg); previewDiv.style.display = 'block'; } } }; img.src = highResImageUrl; } } function onMouseOut(event) { if (!event.relatedTarget || event.relatedTarget.tagName !== 'IMG') { previewDiv.style.display = 'none'; lastHoveredImage = null; } } const observer = new MutationObserver((mutations, obs) => { if (window.location.href.includes('/media')) { createPreviewDiv(); addEventListeners(); } else { removeEventListeners(); if (previewDiv) { previewDiv.style.display = 'none'; } } }); observer.observe(document, { childList: true, subtree: true }); })();