SnapResize
社交媒体图片尺寸调整 · 选择平台,批量导出
拖拽图片到此处,或点击上传
支持批量上传 JPG / PNG / WebP
图片列表
0
张
清空列表
目标平台
Twitter
IG
LinkedIn
FB
TikTok
自定义
调整模式
Fit
Fill
Stretch
按比例缩放至完全显示在画布内
目标尺寸超过原始图片尺寸,图片将被放大,可能导致画质损失
宽度 (px)
高度 (px)
锁定宽高比
原始图片
—
选择图片后显示预览
调整后
—
调整参数后自动预览
下载当前
下载全部(ZIP)
(0)
添加更多
重新开始
处理中...
0%
(function(){var translations={zh:{'upload.drag':'拖拽图片到此处,或点击上传','upload.hint':'支持批量上传 JPG / PNG / WebP','clearAll':'清空列表','label.platform':'目标平台','label.mode':'调整模式','label.width':'宽度 (px)','label.height':'高度 (px)','aspectRatio.lock':'锁定宽高比','preview.original':'原始图片','preview.result':'调整后','placeholder.original':'选择图片后显示预览','placeholder.result':'调整参数后自动预览','warning.resolution':'目标尺寸超过原始图片尺寸,图片将被放大,可能导致画质损失','progress.processing':'处理中...','subtitle':'社交媒体图片尺寸调整 · 选择平台,批量导出'}};function t(key){return(translations['zh']&&translations['zh'][key])||key}window.__=t;document.addEventListener('DOMContentLoaded',function(){document.querySelectorAll('[data-i18n]').forEach(function(el){var key=el.getAttribute('data-i18n');if(key)el.textContent=t(key)})})})();window.addEventListener('error',function(e){console.error('[SnapResize] Uncaught error:',e.error||e.message)});window.addEventListener('unhandledrejection',function(e){console.error('[SnapResize] Unhandled promise rejection:',e.reason)});document.addEventListener('DOMContentLoaded',function(){if(typeof navBar!=='undefined'&&navBar&&typeof navBar.render==='function')navBar.render({site:'snapresize'})}); (function() { // ----- 国际化模块 (i18n) ----- const langDict = { 'zh': { 'subtitle': '社交媒体图片尺寸调整 · 选择平台,批量导出', 'upload.drag': '拖拽图片到此处,或点击上传', 'upload.hint': '支持批量上传 JPG / PNG / WebP', 'clearAll': '清空列表', 'label.platform': '目标平台', 'label.mode': '调整模式', 'label.width': '宽度 (px)', 'label.height': '高度 (px)', 'aspectRatio.lock': '锁定宽高比', 'preview.original': '原始图片', 'preview.result': '调整后', 'placeholder.original': '选择图片后显示预览', 'placeholder.result': '调整参数后自动预览', 'warning.resolution': '目标尺寸超过原始图片尺寸,图片将被放大,可能导致画质损失', 'progress.processing': '处理中...' }, 'en': { 'subtitle': 'Social media image resizing · Pick a platform, batch export', 'upload.drag': 'Drag & drop images here, or click to upload', 'upload.hint': 'Supports JPG / PNG / WebP (batch upload)', 'clearAll': 'Clear all', 'label.platform': 'Target Platform', 'label.mode': 'Resize Mode', 'label.width': 'Width (px)', 'label.height': 'Height (px)', 'aspectRatio.lock': 'Lock aspect ratio', 'preview.original': 'Original', 'preview.result': 'Resized', 'placeholder.original': 'Preview after selecting an image', 'placeholder.result': 'Auto preview after adjusting parameters', 'warning.resolution': 'Target size exceeds original image size; image will be upscaled, quality may degrade', 'progress.processing': 'Processing...' } }; function applyI18n(lang) { var dict = langDict[lang] || langDict['zh']; document.querySelectorAll('[data-i18n]').forEach(function(el) { var key = el.getAttribute('data-i18n'); if (dict[key]) { el.textContent = dict[key]; } }); // Update placeholders if needed var fileInput = document.getElementById('fileInput'); if (fileInput && dict['upload.hint']) { // not necessary } } var userLang = (navigator.language || 'zh').split('-')[0]; if (!langDict[userLang]) userLang = 'zh'; applyI18n(userLang); // Add simple language switcher (top-right corner) var langBar = document.createElement('div'); langBar.style.cssText = 'position:fixed;top:12px;right:12px;z-index:999;display:flex;gap:6px;font-size:12px;'; ['zh','en'].forEach(function(l) { var btn = document.createElement('button'); btn.textContent = l.toUpperCase(); btn.style.cssText = 'background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.2);border-radius:6px;padding:4px 10px;color:#fff;cursor:pointer;font-family:inherit;'; btn.addEventListener('click', function() { applyI18n(l); }); langBar.appendChild(btn); }); document.body.appendChild(langBar); // ----- 导航栏集成 (shared auth) ----- document.addEventListener('DOMContentLoaded', function() { // 如果 nav-bar.js 导出了 NavBar 对象,则渲染导航栏 if (typeof NavBar !== 'undefined' && NavBar.render) { try { NavBar.render(); } catch(e) { console.warn('NavBar.render failed', e); } } else if (typeof renderNavBar !== 'undefined') { try { renderNavBar(); } catch(e) { console.warn('renderNavBar failed', e); } } else { // 如果导航栏未自动生成,手动创建一个占位(但已引用脚本,期望自动挂载) console.log('NavBar not found – ensure ../shared/nav-bar.js is loaded correctly'); } }); // ----- 输入校验 (ui_boundary) ----- function sanitizeNumberInput(inputEl) { inputEl.addEventListener('blur', function() { var val = parseInt(this.value, 10); if (isNaN(val) || val < 1) { this.value = 1; } else if (val > 10000) { this.value = 10000; } }); inputEl.addEventListener('input', function() { var val = parseInt(this.value, 10); if (isNaN(val) || val < 1) { // Not forceful on input, only on blur } }); } var wInput = document.getElementById('widthInput'); var hInput = document.getElementById('heightInput'); if (wInput) sanitizeNumberInput(wInput); if (hInput) sanitizeNumberInput(hInput); // ----- 拖拽防御 (ui_boundary) ----- var uploadArea = document.getElementById('uploadArea'); if (uploadArea) { ['dragenter','dragover','dragleave','drop'].forEach(function(ev) { uploadArea.addEventListener(ev, function(e) { e.preventDefault(); e.stopPropagation(); }); }); } // 全局防止页面跳转 document.addEventListener('dragover', function(e) { e.preventDefault(); }); document.addEventListener('drop', function(e) { e.preventDefault(); }); // ----- 全局错误处理与资源加载监控 (console_errors) ----- window.addEventListener('error', function(e) { if (e.target && (e.target.tagName === 'SCRIPT' || e.target.tagName === 'LINK' || e.target.tagName === 'IMG')) { console.warn('Resource failed to load:', e.target.src || e.target.href); } }, true); // 捕获未处理的 Promise 拒绝 window.addEventListener('unhandledrejection', function(e) { console.error('Unhandled Promise rejection:', e.reason); }); })();