212 lines
6.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图片转PDF</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
margin: 0;
background-color: #f4f4f4;
}
h1 {
font-size: 2.5vw;
margin-bottom: 20px;
color: #333;
}
#image-container {
display: flex;
flex-wrap: wrap;
gap: 15px;
justify-content: center;
margin: 20px 0;
padding: 10px;
border: 2px dashed #ccc;
background-color: #fff;
min-height: 100px;
width: 100%;
max-width: 1200px;
}
.image-item {
position: relative;
border: 1px solid #ccc;
overflow: hidden;
transition: transform 0.2s;
cursor: move; /* 提示用户可以拖拽 */
}
.image-item:hover {
transform: scale(1.05);
}
.image-item img {
width: 100%;
height: 100%;
object-fit: cover;
}
.delete-btn {
position: absolute;
top: 5px;
right: 5px;
background-color: rgb(0, 0, 0);
opacity: 0.5;
color: white;
margin: 0;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
padding: 0;
font-size: 12px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
button {
padding: 10px 20px;
font-size: 16px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-top: 20px;
}
button:hover {
background-color: #0056b3;
}
@media (max-width: 600px) {
h1 {
font-size: 5vw;
}
button {
font-size: 14px;
padding: 8px 16px;
}
}
</style>
</head>
<body>
<h1>图片转PDF</h1>
<input type="file" id="file-input" multiple accept="image/*">
<div id="image-container"></div>
<button id="generate-pdf">生成PDF</button>
<!-- 引入外部库 -->
<script src="../../../libs/Sortable.min.js"></script>
<script src="../../../libs/pdf-lib.min.js"></script>
<script>
const fileInput = document.getElementById('file-input');
const imageContainer = document.getElementById('image-container');
const generateButton = document.getElementById('generate-pdf');
let images = [];
// 文件选择事件
fileInput.addEventListener('change', (e) => {
handleFiles(e.target.files);
});
// 生成PDF
generateButton.addEventListener('click', async () => {
if (images.length === 0) {
alert('请先添加至少一张图片!');
return;
}
const pdfDoc = await PDFLib.PDFDocument.create();
for (const image of images) {
const imgBytes = await fetch(image.src).then(res => res.arrayBuffer());
let img = image.file.type === 'image/png' ?
await pdfDoc.embedPng(imgBytes) :
await pdfDoc.embedJpg(imgBytes);
const page = pdfDoc.addPage([img.width, img.height]);
page.drawImage(img, { x: 0, y: 0, width: img.width, height: img.height });
}
const pdfBytes = await pdfDoc.save();
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '图片合集.pdf';
a.click();
URL.revokeObjectURL(url);
});
// 处理文件
function handleFiles(files) {
Array.from(files).forEach(file => {
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = function(e) {
const imgWrapper = document.createElement('div');
imgWrapper.classList.add('image-item');
const img = document.createElement('img');
img.src = e.target.result;
const deleteBtn = document.createElement('button');
deleteBtn.classList.add('delete-btn');
deleteBtn.innerHTML = '×';
deleteBtn.addEventListener('click', () => {
imgWrapper.remove();
images = images.filter(item => item.src !== img.src);
});
imgWrapper.appendChild(img);
imgWrapper.appendChild(deleteBtn);
imageContainer.appendChild(imgWrapper);
images.push({ src: e.target.result, file });
setImageSize();
};
reader.readAsDataURL(file);
}
});
}
// 获取视口宽度
function getViewportWidth() {
return window.innerWidth || document.documentElement.clientWidth;
}
// 设置图片尺寸
function setImageSize() {
const viewportWidth = getViewportWidth();
const imageItems = document.querySelectorAll('.image-item');
let size = viewportWidth >= 1200 ? 150 : viewportWidth >= 600 ? 100 : 80;
imageItems.forEach(item => {
item.style.width = `${size}px`;
item.style.height = `${size}px`;
});
}
// 监听窗口resize事件
window.addEventListener('resize', setImageSize);
setImageSize();
// 拖拽导入支持
imageContainer.addEventListener('dragover', (e) => {
e.preventDefault();
});
imageContainer.addEventListener('drop', (e) => {
e.preventDefault();
if (e.dataTransfer.files.length > 0) {
handleFiles(e.dataTransfer.files);
}
});
// 初始化 Sortable.js 进行拖拽排序
new Sortable(imageContainer, {
animation: 150,
onEnd: function(evt) {
// 更新 images 数组顺序
const movedItem = images.splice(evt.oldIndex, 1)[0];
images.splice(evt.newIndex, 0, movedItem);
}
});
</script>
</body>
</html>