User:維基小霸王/CSSImageCrop.js

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
function runImageCropTool() {
    var fileDiv = document.getElementById('file');
    if (!fileDiv) {
        console.log('找不到id为 "file" 的元素。请确保你的HTML结构中存在这个元素。');
        return;
    }

    var imgElement = fileDiv.querySelector('img');
    if (!imgElement) {
        console.log('在 id为 "file" 的元素内找不到 <img> 标签。');
        return;
    }

    // 检测 URL 中是否包含 &page=<numbers> 参数
    const urlParams = new URLSearchParams(window.location.search);
    let pageNumber = null;
    if (urlParams.has('page')) {
        const pageParam = urlParams.get('page');
        // 验证 pageParam 是否为数字
        if (/^\d+$/.test(pageParam)) {
            pageNumber = pageParam;
        }
    }

    var isDragging = false;
    var startX, startY, endX, endY;
    var rectOutline = null; // 用于显示矩形轮廓的元素
    var zoomFactor = 1; // 默认放大倍数为 1


    // 创建矩形轮廓的div
    function createRectOutline() {
        if (!rectOutline) {
            rectOutline = document.createElement('div');
            rectOutline.style.border = '2px solid yellow';
            rectOutline.style.position = 'absolute';
            rectOutline.style.pointerEvents = 'none'; // 防止矩形遮挡鼠标事件
            fileDiv.style.position = 'relative'; // 确保矩形相对于fileDiv定位
            fileDiv.appendChild(rectOutline);
        }
    }

    // 更新矩形轮廓的位置和大小
    function updateRectOutline(x1, y1, x2, y2) {
        var left = Math.min(x1, x2);
        var top = Math.min(y1, y2);
        var width = Math.abs(x1 - x2);
        var height = Math.abs(y1 - y2);

        rectOutline.style.left = left + 'px';
        rectOutline.style.top = top + 'px';
        rectOutline.style.width = width + 'px';
        rectOutline.style.height = height + 'px';
    }

    // 清除矩形轮廓
    function clearRectOutline() {
        if (rectOutline) {
            rectOutline.style.width = '0px';
            rectOutline.style.height = '0px';
        }
    }


    fileDiv.addEventListener('mousedown', function(e) {
        e.preventDefault(); // 阻止默认的图片拖动行为  <-- 添加这行代码
        isDragging = true;
        startX = e.offsetX;
        startY = e.offsetY;
        createRectOutline();
    });

    fileDiv.addEventListener('mousemove', function(e) {
        if (isDragging) {
            endX = e.offsetX;
            endY = e.offsetY;
            updateRectOutline(startX, startY, endX, endY);
        }
    });

    fileDiv.addEventListener('mouseup', function(e) {
        if (isDragging) {
            isDragging = false;
            endX = e.offsetX;
            endY = e.offsetY;

            var rect = {
                x1: Math.min(startX, endX),
                y1: Math.min(startY, endY),
                x2: Math.max(startX, endX),
                y2: Math.max(startY, endY)
            };

            // 获取图片文件名 (假设从 imgElement.src 获取,你需要根据实际情况调整)
            var imageSrc = imgElement.src;
            var imageName = mw.config.get('wgTitle');

            // 获取图片原始宽度 (bSize)
            var baseImageWidth = imgElement.naturalWidth;


            // 使用 jquery.ui dialog 显示模板代码和放大倍数输入框
            var modalLoad;
            modalLoad = modalLoad || mw.loader.using('jquery.ui');
            modalLoad.done(function () {
                // 创建包含输入框的对话框内容
                var $dialogContent = $('<div style="display:none;">' +
                    '<label for="zoomFactor">Zoom level: </label>' +
                    '<input type="number" id="zoomFactor" value="1" min="0.1" step="0.1"><br><br>' +
                    '<pre style="white-space: pre-wrap;" id="templateCodeDisplay"></pre>' + // 用于显示模板代码的 <pre> 标签
                    '</div>');

                var $zoomFactorInput = $dialogContent.find('#zoomFactor'); // 获取放大倍数输入框 jQuery 对象
                var $templateCodeDisplay = $dialogContent.find('#templateCodeDisplay'); // 获取模板代码显示区域 jQuery 对象


                // 定义更新模板代码的函数 (方便复用)
                function updateTemplateCode() {
                    zoomFactor = parseFloat($zoomFactorInput.val());
                    if (isNaN(zoomFactor) || zoomFactor <= 0) {
                        zoomFactor = 1; // 确保放大倍数有效
                        $zoomFactorInput.val(1);
                    }

                    // 计算裁剪参数,应用放大倍数
                    var bSize = Math.round(baseImageWidth * zoomFactor);
                    var cWidth = Math.round((rect.x2 - rect.x1) * zoomFactor);
                    var cHeight = Math.round((rect.y2 - rect.y1) * zoomFactor);
                    var oTop = Math.round(rect.y1 * zoomFactor);
                    var oLeft = Math.round(rect.x1 * zoomFactor);


                    // 构建 CSS image crop 模板代码
                    let templateCode = `{{CSS image crop
|Image          = ${imageName}
|bSize          = ${bSize}
|cWidth         = ${cWidth}
|cHeight        = ${cHeight}
|oTop           = ${oTop}
|oLeft          = ${oLeft}
|Description    = `;

                    // 如果 pageNumber 不为 null,则添加 |page 参数
                    if (pageNumber !== null) {
                        templateCode += `
|Page           = ${pageNumber}`;
                    }

                    templateCode += `
}}`;

                    // 更新对话框中的模板代码显示
                    $templateCodeDisplay.text(templateCode);
                }


                $dialogContent.dialog({
                    title: 'CSS Image Crop Template',
                    modal: true,
                    width: 610,
                    height: 'auto',
                    buttons: {
                        "Copy": function() {
                            // 获取模板代码
                            var templateCode = $templateCodeDisplay.text();

                            // 复制到剪贴板
                            navigator.clipboard.writeText(templateCode).then(function() {
                                alert('Template copied.');
                            }).catch(function(err) {
                                console.error('Template copy failed: ', err);
                                alert('Template copy failed. Copy yourself.');
                            });
                        },
                        "Close": function() {
                            $(this).dialog("close");
                        }
                    },
                     open: function() {
                        // 首次打开对话框时,使用默认放大倍数初始化模板代码
                        updateTemplateCode();
                        // 默认焦点在放大倍数输入框
                        $zoomFactorInput.focus();
                    },
                    close: function() {
                        $(this).remove();
                    }
                });


                //  添加 input 事件监听器,在放大倍数输入框内容改变时实时更新模板代码
                $zoomFactorInput.on('input', function() {
                    updateTemplateCode(); // 调用更新模板代码的函数
                });


            });
        }
    });

    fileDiv.addEventListener('mouseleave', function(e) {
        if (isDragging) {
            isDragging = false;
            clearRectOutline(); // 鼠标移出图片区域时清除矩形
        }
    });


    // 阻止默认的点击跳转行为
    fileDiv.addEventListener('click', function(event) {
        event.preventDefault(); // 阻止默认行为
    });

}

var node = mw.util.addPortletLink(
    'filetoc',
    'javascript:runImageCropTool();',
    'CSS Image Crop'
);