180 lines
5.2 KiB
JavaScript
180 lines
5.2 KiB
JavaScript
// 二维码功能 - 简洁可靠
|
|
(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();
|
|
})();
|