Instagram, Instant zoom

x2/x4 zoom for images/videos on timeline

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Instagram, Instant zoom
// @name:ja      Instagram, ズーム
// @namespace    http://tampermonkey.net/
// @version      2025-03-29.2
// @description  x2/x4 zoom for images/videos on timeline
// @description:ja タイムラインで画像をx2/x4ズームできます
// @author       You
// @match        https://*.instagram.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=instagram.com
// @grant        GM.addStyle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    GM.addStyle(`
    ._aagv img, video {
        transition: transform 0.06s linear;
    }
    `);

    var zoomMultipoly = 2;

    document.body.addEventListener("mousemove", e => e.target.classList.contains("_aagw") && zoom(e));
    document.body.addEventListener("mouseout", e => e.target.classList.contains("_aagw") && cancelZoom(e));
    document.body.addEventListener("mousedown", e => e.target.classList.contains("_aagw") && moreZoom(e));
    document.body.addEventListener("mouseup", e => e.target.classList.contains("_aagw") && moreZoomOut(e));

    document.body.addEventListener("mousemove", e => e.target.role == "presentation" && zoomVideo(e));
    document.body.addEventListener("mouseout", e => e.target.role == "presentation" && cancelZoomVideo(e));

    function zoom(e) {
        const cover = e.target;
        var image = cover.previousSibling.firstChild;
        if (image.tagName != "IMG") return;

        const x = - (e.offsetX / cover.offsetWidth - 0.5) * (1 - 1 / zoomMultipoly) * 100;
        const y = - (e.offsetY / cover.offsetHeight - 0.5) * (1 - 1 / zoomMultipoly) * 100;
        image.style.transform = `scale(${zoomMultipoly}) translate(${x}%,${y}%)`;
    }

    function cancelZoom(e) {
        const image = e.target.previousSibling.firstChild;
        if (image.tagName != "IMG") return;

        image.style.transform = "";
        zoomMultipoly = 2;
    }

    function moreZoom(e) {
        zoomMultipoly = 4;
        zoom(e);
    }

    function moreZoomOut(e) {
        zoomMultipoly = 2;
        zoom(e);
    }

    function zoomVideo(e) {
        const cover = e.target;
        var video = e.target.parentNode.parentNode.parentNode.firstChild;
        if (video.tagName != "VIDEO") return;

        const x = - (e.offsetX / cover.offsetWidth - 0.5) * (1 - 1 / zoomMultipoly) * 100;
        const y = - (e.offsetY / cover.offsetHeight - 0.5) * (1 - 1 / zoomMultipoly) * 100;
        video.style.transform = `scale(${zoomMultipoly}) translate(${x}%,${y}%)`;
    }

    function cancelZoomVideo(e) {
        var video = e.target.parentNode.parentNode.parentNode.firstChild;
        if (video.tagName != "VIDEO") return;

        video.style.transform = "";
        zoomMultipoly = 2;
    }

})();