feat(邀请函): 添加二维码生成功能
- 新增二维码按钮及弹窗界面 - 实现二维码生成、预览和添加到画布功能 - 支持二维码在画布上的拖拽操作 - 添加相关样式和事件处理
This commit is contained in:
179
js/qr.js
Normal file
179
js/qr.js
Normal file
@@ -0,0 +1,179 @@
|
||||
// 二维码功能 - 简洁可靠
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// 获取元素
|
||||
const btn = document.getElementById('qr-btn');
|
||||
const modal = document.getElementById('qr-modal');
|
||||
const input = document.getElementById('qr-input');
|
||||
const preview = document.getElementById('qr-preview');
|
||||
const closeBtn = document.querySelector('.qr-close');
|
||||
const cancelBtn = document.querySelector('.qr-cancel');
|
||||
const okBtn = document.querySelector('.qr-ok');
|
||||
|
||||
if (!btn || !modal) return;
|
||||
|
||||
let currentQR = null;
|
||||
let qrCount = 0;
|
||||
|
||||
// 检查背景图并显示按钮
|
||||
function checkBg() {
|
||||
const container = document.getElementById('imageContainer');
|
||||
if (!container) return;
|
||||
// 排除二维码图片,只检查背景图
|
||||
const img = container.querySelector('img:not([data-type="qrcode"])');
|
||||
if (img && img.src && !img.src.endsWith(window.location.href)) {
|
||||
btn.classList.add('show');
|
||||
} else {
|
||||
btn.classList.remove('show');
|
||||
}
|
||||
}
|
||||
|
||||
// 监听背景图变化
|
||||
const observer = new MutationObserver(checkBg);
|
||||
const container = document.getElementById('imageContainer');
|
||||
if (container) {
|
||||
observer.observe(container, { childList: true, subtree: true });
|
||||
}
|
||||
setInterval(checkBg, 500);
|
||||
|
||||
// 打开弹窗
|
||||
function openModal() {
|
||||
modal.classList.add('active');
|
||||
input.value = '';
|
||||
preview.innerHTML = '';
|
||||
currentQR = null;
|
||||
input.focus();
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
function closeModal() {
|
||||
modal.classList.remove('active');
|
||||
}
|
||||
|
||||
// 生成预览
|
||||
function genPreview() {
|
||||
const text = input.value.trim();
|
||||
if (!text) {
|
||||
preview.innerHTML = '';
|
||||
currentQR = null;
|
||||
return;
|
||||
}
|
||||
preview.innerHTML = '';
|
||||
try {
|
||||
currentQR = new QRCode(preview, {
|
||||
text: text,
|
||||
width: 128,
|
||||
height: 128
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('生成失败', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加到画布
|
||||
function addToCanvas() {
|
||||
if (!currentQR) {
|
||||
alert('请输入内容');
|
||||
return;
|
||||
}
|
||||
const canvas = preview.querySelector('canvas');
|
||||
if (!canvas) return;
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = canvas.toDataURL();
|
||||
img.className = 'qr-item';
|
||||
img.dataset.type = 'qrcode';
|
||||
img.style.width = '100px';
|
||||
img.style.height = '100px';
|
||||
|
||||
const container = document.getElementById('imageContainer');
|
||||
const rect = container.getBoundingClientRect();
|
||||
img.style.left = (rect.width / 2 - 50) + 'px';
|
||||
img.style.top = (rect.height / 2 - 50) + 'px';
|
||||
|
||||
container.appendChild(img);
|
||||
makeDraggable(img);
|
||||
closeModal();
|
||||
|
||||
if (typeof saveState === 'function') saveState();
|
||||
}
|
||||
|
||||
// 拖拽功能 - 支持鼠标和触摸
|
||||
function makeDraggable(el) {
|
||||
let dragging = false;
|
||||
let startX, startY, startLeft, startTop;
|
||||
|
||||
function startDrag(clientX, clientY) {
|
||||
dragging = true;
|
||||
startX = clientX;
|
||||
startY = clientY;
|
||||
startLeft = parseInt(el.style.left) || 0;
|
||||
startTop = parseInt(el.style.top) || 0;
|
||||
}
|
||||
|
||||
function moveDrag(clientX, clientY) {
|
||||
if (!dragging) return;
|
||||
el.style.left = (startLeft + clientX - startX) + 'px';
|
||||
el.style.top = (startTop + clientY - startY) + 'px';
|
||||
}
|
||||
|
||||
function endDrag() {
|
||||
if (dragging) {
|
||||
dragging = false;
|
||||
if (typeof saveState === 'function') saveState();
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标事件
|
||||
el.addEventListener('mousedown', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
startDrag(e.clientX, e.clientY);
|
||||
});
|
||||
|
||||
// 触摸事件
|
||||
el.addEventListener('touchstart', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (e.touches.length === 1) {
|
||||
startDrag(e.touches[0].clientX, e.touches[0].clientY);
|
||||
}
|
||||
}, { passive: false });
|
||||
|
||||
// 全局移动事件
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
moveDrag(e.clientX, e.clientY);
|
||||
});
|
||||
|
||||
document.addEventListener('touchmove', function(e) {
|
||||
if (dragging && e.touches.length === 1) {
|
||||
e.preventDefault();
|
||||
moveDrag(e.touches[0].clientX, e.touches[0].clientY);
|
||||
}
|
||||
}, { passive: false });
|
||||
|
||||
// 全局结束事件
|
||||
document.addEventListener('mouseup', endDrag);
|
||||
document.addEventListener('touchend', endDrag);
|
||||
}
|
||||
|
||||
// 事件绑定
|
||||
btn.addEventListener('click', openModal);
|
||||
closeBtn.addEventListener('click', closeModal);
|
||||
cancelBtn.addEventListener('click', closeModal);
|
||||
okBtn.addEventListener('click', addToCanvas);
|
||||
modal.addEventListener('click', function(e) {
|
||||
if (e.target === modal) closeModal();
|
||||
});
|
||||
|
||||
// 输入防抖
|
||||
let timer;
|
||||
input.addEventListener('input', function() {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(genPreview, 300);
|
||||
});
|
||||
|
||||
// 初始检查
|
||||
checkBg();
|
||||
})();
|
||||
29
js/script.js
29
js/script.js
@@ -3172,6 +3172,35 @@
|
||||
drawTextOnCanvasHD(ctx, textInput, scale);
|
||||
}
|
||||
});
|
||||
|
||||
// 绘制二维码
|
||||
const qrImages = container.querySelectorAll('img[data-type="qrcode"]');
|
||||
for (const qrImg of qrImages) {
|
||||
if (!qrImg.classList.contains('layer-hidden')) {
|
||||
const rect = qrImg.getBoundingClientRect();
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const x = (rect.left - containerRect.left) * scale;
|
||||
const y = (rect.top - containerRect.top) * scale;
|
||||
const w = rect.width * scale;
|
||||
const h = rect.height * scale;
|
||||
|
||||
// 确保图片已加载
|
||||
if (qrImg.complete && qrImg.naturalWidth > 0) {
|
||||
ctx.drawImage(qrImg, x, y, w, h);
|
||||
} else {
|
||||
// 等待图片加载完成
|
||||
await new Promise(resolve => {
|
||||
qrImg.onload = () => {
|
||||
ctx.drawImage(qrImg, x, y, w, h);
|
||||
resolve();
|
||||
};
|
||||
qrImg.onerror = () => resolve();
|
||||
// 超时处理
|
||||
setTimeout(resolve, 100);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 记录总耗时
|
||||
const endTime = performance.now();
|
||||
|
||||
Reference in New Issue
Block a user