夯-拉排名生成器
由豆包生成。双击更改标签名称,可随意拖曳。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>从夯到拉排名生成器</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"> <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script> <script> tailwind.config = { theme: { extend: { colors: { 'rank-1': '#e63946', 'rank-2': '#fb8500', 'rank-3': '#ffb703', 'rank-4': '#6c757d', 'rank-5': '#212529', }, fontFamily: { sans: ['Inter', 'system-ui', 'sans-serif'], }, } } } </script> <style type="text/tailwindcss"> @layer utilities { .rank-item { @apply w-full h-[20%] flex items-center px-4 text-white font-bold text-lg border-b border-white/20; } .draggable-item { @apply absolute bg-white/90 p-2 rounded shadow-md cursor-move border border-gray-200 whitespace-nowrap; } .canvas-area { @apply relative w-full h-[600px] border-2 border-gray-300 bg-gray-50 overflow-hidden; } .rank-column { @apply w-32 h-full border-r-2 border-gray-300; } .content-area { @apply absolute left-32 right-0 top-0 bottom-0 p-4; } .divider-line { @apply absolute w-full h-px bg-gray-300 left-0; } } </style> </head> <body class="bg-gray-100 p-4"> <div class="max-w-4xl mx-auto bg-white rounded-lg shadow-lg p-4"> <!-- 工具栏 --> <div class="flex justify-between items-center mb-4"> <div> <button id="add-item" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded flex items-center"> <i class="fa fa-plus mr-2"></i>添加项目 </button> <input type="text" id="item-text" placeholder="输入项目名称" class="ml-2 px-3 py-2 border border-gray-300 rounded"> </div> <button id="export-btn" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded flex items-center"> <i class="fa fa-download mr-2"></i>导出图像 </button> </div> <!-- 主要画布区域 --> <div id="meme-canvas" class="canvas-area"> <!-- 排名等级列 --> <div class="rank-column float-left"> <div class="rank-item bg-rank-1">夯</div> <div class="rank-item bg-rank-2">顶级</div> <div class="rank-item bg-rank-3">人上人</div> <div class="rank-item bg-rank-4">NPC</div> <div class="rank-item bg-rank-5">拉完了</div> </div> <!-- 内容区域 --> <div id="content-area" class="content-area"> <!-- 等级分割线 - 精确对齐到每个等级项的底部 --> <div class="divider-line" style="top: 20%"></div> <div class="divider-line" style="top: 40%"></div> <div class="divider-line" style="top: 60%"></div> <div class="divider-line" style="top: 80%"></div> <!-- 可拖拽项目将在这里动态生成 --> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', () => { const contentArea = document.getElementById('content-area'); const addButton = document.getElementById('add-item'); const itemInput = document.getElementById('item-text'); const exportButton = document.getElementById('export-btn'); const memeCanvas = document.getElementById('meme-canvas'); let draggedItem = null; // 添加新的可拖拽项目 addButton.addEventListener('click', () => { const text = itemInput.value.trim() || '新项目'; createDraggableItem(text); itemInput.value = ''; itemInput.focus(); }); // 按Enter键添加项目 itemInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { addButton.click(); } }); // 创建可拖拽项目 function createDraggableItem(text) { const item = document.createElement('div'); const itemId = 'item-' + Date.now(); // 生成唯一ID item.id = itemId; item.className = 'draggable-item'; item.textContent = text; item.draggable = true; // 设置初始位置 item.style.left = '50px'; item.style.top = '50px'; // 添加删除按钮 const deleteBtn = document.createElement('button'); deleteBtn.className = 'ml-2 text-red-500 hover:text-red-700'; deleteBtn.innerHTML = '<i class="fa fa-times"></i>'; deleteBtn.addEventListener('click', (e) => { e.stopPropagation(); item.remove(); }); item.appendChild(deleteBtn); // 双击可编辑文本 item.addEventListener('dblclick', () => { const currentText = item.firstChild.textContent.trim(); const newText = prompt('编辑项目:', currentText); if (newText !== null && newText.trim() !== '') { item.firstChild.textContent = newText.trim(); } }); // 拖拽功能 item.addEventListener('dragstart', (e) => { draggedItem = item; item.classList.add('opacity-50'); e.dataTransfer.setData('text/plain', JSON.stringify({ id: itemId, x: e.clientX - item.getBoundingClientRect().left, y: e.clientY - item.getBoundingClientRect().top })); }); item.addEventListener('dragend', () => { item.classList.remove('opacity-50'); draggedItem = null; }); contentArea.appendChild(item); } // 处理拖放区域 contentArea.addEventListener('dragover', (e) => { e.preventDefault(); }); contentArea.addEventListener('drop', (e) => { e.preventDefault(); if (!draggedItem) return; const data = JSON.parse(e.dataTransfer.getData('text/plain')); const rect = contentArea.getBoundingClientRect(); const x = e.clientX - rect.left - data.x; const y = e.clientY - rect.top - data.y; // 确保元素不会超出内容区域 const maxX = rect.width - draggedItem.offsetWidth; const maxY = rect.height - draggedItem.offsetHeight; draggedItem.style.left = `${Math.max(0, Math.min(x, maxX))}px`; draggedItem.style.top = `${Math.max(0, Math.min(y, maxY))}px`; }); // 导出图像功能 exportButton.addEventListener('click', () => { html2canvas(memeCanvas, { scale: 2, useCORS: true, logging: false }).then(canvas => { const link = document.createElement('a'); link.download = '从夯到拉排名.png'; link.href = canvas.toDataURL('image/png'); link.click(); }); }); // 初始添加几个示例项目 createDraggableItem('示例A'); createDraggableItem('示例B'); createDraggableItem('示例C'); }); </script> </body> </html>
