fix: 缩小顶部工具栏元素宽度,优化移动端保存图片到相册
This commit is contained in:
@@ -31,7 +31,9 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
padding: 10px 24px;
|
min-width: 72px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 12px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
@@ -40,6 +42,9 @@ html, body {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn:active {
|
.btn:active {
|
||||||
@@ -47,6 +52,7 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
|
min-width: 100px;
|
||||||
background: #4a90e2;
|
background: #4a90e2;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-color: #4a90e2;
|
border-color: #4a90e2;
|
||||||
|
|||||||
138
js/script.js
138
js/script.js
@@ -1766,7 +1766,7 @@
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const tipText = document.createElement('p');
|
const tipText = document.createElement('p');
|
||||||
tipText.textContent = '预览图片';
|
tipText.textContent = '长按图片保存到相册';
|
||||||
tipText.style.cssText = `
|
tipText.style.cssText = `
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@@ -1778,16 +1778,41 @@
|
|||||||
img.src = dataUrl;
|
img.src = dataUrl;
|
||||||
img.style.cssText = `
|
img.style.cssText = `
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 80vh;
|
max-height: 70vh;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 4px 20px rgba(255,255,255,0.2);
|
box-shadow: 0 4px 20px rgba(255,255,255,0.2);
|
||||||
|
-webkit-touch-callout: default;
|
||||||
|
-webkit-user-select: auto;
|
||||||
|
user-select: auto;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const btnContainer = document.createElement('div');
|
||||||
|
btnContainer.style.cssText = `
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const saveBtn = document.createElement('button');
|
||||||
|
saveBtn.textContent = '保存到相册';
|
||||||
|
saveBtn.style.cssText = `
|
||||||
|
padding: 12px 30px;
|
||||||
|
font-size: 16px;
|
||||||
|
background: #007AFF;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
|
saveBtn.onclick = async () => {
|
||||||
|
tipOverlay.remove();
|
||||||
|
await saveImageToGallery(dataUrl);
|
||||||
|
};
|
||||||
|
|
||||||
const closeBtn = document.createElement('button');
|
const closeBtn = document.createElement('button');
|
||||||
closeBtn.textContent = '关闭';
|
closeBtn.textContent = '关闭';
|
||||||
closeBtn.style.cssText = `
|
closeBtn.style.cssText = `
|
||||||
margin-top: 20px;
|
padding: 12px 30px;
|
||||||
padding: 12px 40px;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
color: #333;
|
color: #333;
|
||||||
@@ -1797,12 +1822,70 @@
|
|||||||
`;
|
`;
|
||||||
closeBtn.onclick = () => tipOverlay.remove();
|
closeBtn.onclick = () => tipOverlay.remove();
|
||||||
|
|
||||||
|
btnContainer.appendChild(saveBtn);
|
||||||
|
btnContainer.appendChild(closeBtn);
|
||||||
tipOverlay.appendChild(tipText);
|
tipOverlay.appendChild(tipText);
|
||||||
tipOverlay.appendChild(img);
|
tipOverlay.appendChild(img);
|
||||||
tipOverlay.appendChild(closeBtn);
|
tipOverlay.appendChild(btnContainer);
|
||||||
document.body.appendChild(tipOverlay);
|
document.body.appendChild(tipOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 保存图片到相册
|
||||||
|
async function saveImageToGallery(dataUrl) {
|
||||||
|
const filename = '邀请函_' + Date.now() + '.png';
|
||||||
|
|
||||||
|
// 尝试使用 File System Access API (Android/Chrome)
|
||||||
|
if ('showSaveFilePicker' in window) {
|
||||||
|
try {
|
||||||
|
const blob = await (await fetch(dataUrl)).blob();
|
||||||
|
const handle = await window.showSaveFilePicker({
|
||||||
|
suggestedName: filename,
|
||||||
|
types: [{
|
||||||
|
description: 'PNG 图片',
|
||||||
|
accept: { 'image/png': ['.png'] }
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
const writable = await handle.createWritable();
|
||||||
|
await writable.write(blob);
|
||||||
|
await writable.close();
|
||||||
|
showToast('图片已保存到相册');
|
||||||
|
return;
|
||||||
|
} catch (err) {
|
||||||
|
console.log('File System Access API 失败,使用传统方式');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试使用 Web Share API (iOS Safari)
|
||||||
|
if (navigator.share && navigator.canShare) {
|
||||||
|
try {
|
||||||
|
const blob = await (await fetch(dataUrl)).blob();
|
||||||
|
const file = new File([blob], filename, { type: 'image/png' });
|
||||||
|
|
||||||
|
if (navigator.canShare({ files: [file] })) {
|
||||||
|
await navigator.share({
|
||||||
|
files: [file],
|
||||||
|
title: '邀请函',
|
||||||
|
text: '保存邀请函图片'
|
||||||
|
});
|
||||||
|
showToast('图片已分享');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Web Share API 失败,使用传统方式');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传统下载方式
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.download = filename;
|
||||||
|
link.href = dataUrl;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
|
||||||
|
showToast('图片已保存,请在相册中查看');
|
||||||
|
}
|
||||||
|
|
||||||
// 隐藏右键菜单
|
// 隐藏右键菜单
|
||||||
function hideContextMenu() {
|
function hideContextMenu() {
|
||||||
const existingMenu = document.getElementById('contextMenu');
|
const existingMenu = document.getElementById('contextMenu');
|
||||||
@@ -2039,12 +2122,9 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
`;
|
`;
|
||||||
saveBtn.onclick = () => {
|
saveBtn.onclick = async () => {
|
||||||
tipOverlay.remove();
|
tipOverlay.remove();
|
||||||
const link = document.createElement('a');
|
await saveImageToGallery(dataUrl);
|
||||||
link.download = filename;
|
|
||||||
link.href = dataUrl;
|
|
||||||
link.click();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const cancelBtn = document.createElement('button');
|
const cancelBtn = document.createElement('button');
|
||||||
@@ -2096,6 +2176,44 @@
|
|||||||
savePanel.insertBefore(previewBtn, saveBtn);
|
savePanel.insertBefore(previewBtn, saveBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示 Toast 提示
|
||||||
|
function showToast(message) {
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
color: #fff;
|
||||||
|
padding: 16px 24px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 10001;
|
||||||
|
pointer-events: none;
|
||||||
|
animation: fadeInOut 2s ease forwards;
|
||||||
|
`;
|
||||||
|
toast.textContent = message;
|
||||||
|
|
||||||
|
// 添加动画样式
|
||||||
|
if (!document.getElementById('toastStyle')) {
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.id = 'toastStyle';
|
||||||
|
style.textContent = `
|
||||||
|
@keyframes fadeInOut {
|
||||||
|
0% { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
|
||||||
|
20% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||||
|
80% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||||
|
100% { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.appendChild(toast);
|
||||||
|
setTimeout(() => toast.remove(), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
// 窗口大小改变时更新图片位置和边界
|
// 窗口大小改变时更新图片位置和边界
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
if (currentImage) {
|
if (currentImage) {
|
||||||
|
|||||||
Reference in New Issue
Block a user