吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 548|回复: 15
上一主题 下一主题
收起左侧

[其他原创] 文件贴 姓名贴带卡通图案,横版、竖版。 学科袋贴 HTML MIMO ai

[复制链接]
跳转到指定楼层
楼主
遇见你 发表于 2026-8-31 18:07 回帖奖励
本帖最后由 遇见你 于 2026-8-31 18:13 编辑



用A4纸+打印机+双面胶,就能批量做姓名贴和学科贴,纯网页工具,打开即用,不用装任何软件。核心亮点[color=var(--tw-prose-bold)]一、学科管理,一打搞定
  • 支持添加多个学科(语文、数学、英语……),标签按顺序循环分配,一打印全是不同学科,不浪费
  • 也可以点击任意标签上的学科文字单独修改,灵活得很
[color=var(--tw-prose-bold)]二、姓名/班级/学号统一修改
  • 姓名改一次,全部标签同步更新
  • 班级、学号同理,统一管理,不用一张张改
[color=var(--tw-prose-bold)]三、每个字段独立定制
  • 每个选项(学科、姓名、班级、学号)都有独立的:字体选择、字号滑块、加粗开关、文字颜色、背景颜色
  • 比如姓名用楷体加粗,学科用黑体不加粗,随你搭配
[color=var(--tw-prose-bold)]四、标签尺寸自由调节
  • 宽度、高度都有滑块,拖动实时看到每页排多少张
  • 大标签、小标签随时切换
[color=var(--tw-prose-bold)]五、竖版/横版一键切换
  • 竖版适合长条贴纸,横版适合方正标签,一键切换布局
[color=var(--tw-prose-bold)]六、图标装饰
  • 20个emoji快捷选择,支持自定义emoji,还支持上传本地图片当图标
  • 图标可循环排列、统一显示或关闭
[color=var(--tw-prose-bold)]七、所见即所得
  • 所有调整(字号、颜色、尺寸)都是滑块拖动实时预览,打印前就能看到最终效果
  • 虚线边框方便裁剪,打印后沿线剪开就能用
[color=var(--tw-prose-bold)]八、零门槛
  • 就是一个HTML文件,用浏览器打开就能用
  • Ctrl+P直接打印,A4纸100%缩放,取消页眉页脚
适合谁用
  • 老师批量做学生姓名贴、学科贴
  • 家长给孩子做书本标签
  • 办公室做文件分类标签





以上内容是AI总结介绍的。名字是统一修改的。如果要是老师什么的用的话,要弄不同的名字,可以把代码贴进AI再问,让它再改一次,可以单独修改名字。


需要的东西,彩色打印机、A4纸带背胶的。这个平台什么拼多多、淘宝,还有京东有小红包的话,便宜得很,几块钱就有四五十张。


然后, Kimi mimo DeepSeek 豆包,DeepSeek 豆包让我用Excel表格。只有MIMO最开始居然出的是HTML。我靠,把另外两个扔了。然后Kimi白天是真不能用,哎呀,等了半天,不好意思,刚刚和Kimi聊的人太多了。Kimi有点累了,可以晚点再问我一遍。
Kimi出的结果也还行,写的代码。不过白天真不能用,哎,真的只能12点以后,半夜流畅。


MIMO 跟它聊点实时社会新闻什么的,它不敢说,像个笨蛋一样装傻充愣。让它写点这些东西还可以,嘿嘿嘿。


一楼是两个最终的代码,一个是姓名贴,包括横版、竖版。还有一个是学科带的贴,带学科、班级、学号、姓名。姓名贴图标库用的是https://www.iconfont.cn/   这里面有些图标只能自用,不能商用。注意注意注意,不能商用。商用收费


二楼的话是姓名贴的横版和竖版分别的,不能设置背景颜色,初始我感觉还行, 留着备个份吧。






有想法改进的话,直接复制代码给AI,让它再改。哎,有新的改版圈我一下。这玩意还有点好玩,哈哈。哎呀,折腾了一下午,还可以感觉。



<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名贴生成器</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Long+Cang&family=Ma+Shan+Zheng&family=ZCOOL+QingKe+HuangYou&family=ZCOOL+XiaoWei&family=Zhi+Mang+Xing&family=Noto+Sans+SC:wght@300;400;500;700&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
    <style>
        @page{size:A4 portrait;margin:6mm 9mm}
        *{margin:0;padding:0;box-sizing:border-box}
        body{font-family:"Microsoft YaHei","PingFang SC",sans-serif;background:#f5f2ec}

        .controls{
            position:sticky;top:0;z-index:100;
            padding:12px 20px 8px;
            background:linear-gradient(145deg,#1a1a1a 0%,#252018 100%);
            color:#ddd8ce;font-size:13px;
            box-shadow:0 4px 24px rgba(0,0,0,0.3);border-bottom:1px solid #3a3530;
        }
        .row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:7px}
        .row:last-child{margin-bottom:0}
        .row-title{font-size:17px;font-weight:700;color:#fff;letter-spacing:0.06em}
        .divider{width:1px;height:18px;background:#4a4540;flex-shrink:0}
        label{font-weight:500;white-space:nowrap;font-size:12px;color:#bbb5a8}
        .label-sm{font-size:11px;color:#999;white-space:nowrap}

        input[type="text"],select{
            padding:5px 8px;font-size:13px;border:1px solid #555;
            border-radius:5px;background:#2e2e2e;color:#eee;outline:none;transition:border-color .2s;
        }
        input[type="text"]:focus,select:focus{border-color:#c8a951}
        select{cursor:pointer}
        .inp-name{width:78px}
        #customIconInput{width:50px;text-align:center;font-size:15px}

        input[type="range"]{
            -webkit-appearance:none;height:5px;border-radius:3px;background:#444;outline:none;cursor:pointer;
        }
        input[type="range"]::-webkit-slider-thumb{
            -webkit-appearance:none;width:15px;height:15px;border-radius:50%;
            background:#c8a951;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,0.3);
            transition:transform .15s;
        }
        input[type="range"]::-webkit-slider-thumb:hover{transform:scale(1.15)}
        .slider-size{width:56px}
        .slider-tag{width:82px}

        .pt-badge{
            display:inline-block;min-width:28px;text-align:center;
            padding:1px 5px;border-radius:3px;font-size:11px;
            font-weight:600;color:#c8a951;background:#2a2520;
        }
        .grid-info{
            font-size:12px;color:#c8a951;font-weight:600;
            background:#2a2520;padding:3px 10px;border-radius:4px;white-space:nowrap;
        }

        .bold-btn{
            width:26px;height:26px;display:flex;align-items:center;justify-content:center;
            border:2px solid #555;border-radius:4px;cursor:pointer;
            font-size:13px;font-weight:900;background:#2e2a26;color:#888;
            transition:all .15s;user-select:none;
        }
        .bold-btn:hover{border-color:#999;color:#bbb}
        .bold-btn.active{border-color:#c8a951;color:#c8a951;background:#332e22}

        .field-font-select{
            padding:4px 4px;font-size:11px;border:1px solid #444;
            border-radius:4px;background:#2a2a2a;color:#ccc;cursor:pointer;max-width:110px;
        }

        input[type="color"]{
            -webkit-appearance:none;border:2px solid #555;border-radius:4px;
            width:26px;height:26px;padding:0;cursor:pointer;background:#2a2a2a;transition:border-color .15s;
        }
        input[type="color"]:hover{border-color:#c8a951}
        input[type="color"]::-webkit-color-swatch-wrapper{padding:1px}
        input[type="color"]::-webkit-color-swatch{border-radius:2px;border:none}
        .color-group{
            display:inline-flex;align-items:center;gap:3px;
            padding:2px 6px;background:#252220;border-radius:4px;
        }
        .color-reset{
            width:18px;height:18px;display:flex;align-items:center;justify-content:center;
            font-size:10px;color:#777;cursor:pointer;border-radius:2px;
            background:transparent;border:1px solid #444;transition:all .15s;
        }
        .color-reset:hover{color:#e88;border-color:#888;background:#3a2a2a}

        .btn{padding:6px 14px;border:none;border-radius:5px;cursor:pointer;font-size:12px;font-weight:600;transition:all .2s}
        .btn-sm{padding:4px 10px;font-size:11px}
        .btn-add{background:#4a6e3a;color:#c8e0b4}.btn-add:hover{background:#5a8248}
        .btn-clear{background:#5a3a3a;color:#e0b4b4}.btn-clear:hover{background:#6e4848}
        .btn-print{background:#c8a951;color:#1a1a1a;font-size:13px;padding:6px 18px}
        .btn-print:hover{background:#d4b85e;transform:translateY(-1px)}
        .btn-upload{background:#3a5a6e;color:#b4d4e0;position:relative;overflow:hidden}
        .btn-upload:hover{background:#4a6e82}
        .btn-upload input[type="file"]{position:absolute;inset:0;opacity:0;cursor:pointer;font-size:0}
        .hint{font-size:10px;color:#666}

        .preset-icons{display:flex;gap:3px;flex-wrap:wrap}
        .preset-btn{
            width:28px;height:28px;display:flex;align-items:center;justify-content:center;
            border:2px solid #4a4540;border-radius:5px;cursor:pointer;font-size:15px;
            background:#2e2a26;transition:all .15s;user-select:none;
        }
        .preset-btn:hover{border-color:#c8a951;background:#3a3630;transform:scale(1.12)}

        .queue-area{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
        .queue-items{
            display:flex;gap:3px;align-items:center;flex-wrap:wrap;min-height:28px;
            padding:3px 7px;background:#242220;border-radius:5px;border:1px solid #3a3835;
            min-width:120px;max-width:48vw;
        }
        .queue-tag{
            display:inline-flex;align-items:center;gap:2px;padding:2px 5px;
            background:#333028;border-radius:4px;font-size:14px;cursor:pointer;transition:background .15s;
        }
        .queue-tag:hover{background:#5a3a3a}
        .queue-tag img{width:16px;height:16px;object-fit:contain;border-radius:2px}
        .queue-tag .rm{font-size:8px;color:#777;margin-left:1px}
        .queue-tag:hover .rm{color:#e88}
        .queue-empty{color:#666;font-size:11px;font-style:italic}

        .mode-group{display:flex;border-radius:5px;overflow:hidden;border:1px solid #555}
        .mode-btn{
            padding:4px 11px;font-size:11px;font-weight:500;cursor:pointer;
            background:#2e2e2e;color:#999;border:none;transition:all .2s;
        }
        .mode-btn.active{background:#c8a951;color:#1a1a1a}
        .mode-btn:hover:not(.active){background:#3a3a3a}

        /* 预览 */
        .preview-field{
            display:flex;align-items:center;gap:4px;padding:4px 10px;border-radius:4px;
        }
        .preview-field .pf-label{font-size:10px;color:#777;white-space:nowrap}
        .preview-field .pf-sample{white-space:nowrap;line-height:1}

        /* 网格 */
        .page-wrap{padding:3mm 0 10mm;display:flex;justify-content:center}
        .grid{display:grid;justify-content:center;align-content:start}

        /* 竖版 tag */
        .tag-v{
            display:flex;flex-direction:column;align-items:center;justify-content:space-around;
            padding:1mm 0.5mm;
            -webkit-print-color-adjust:exact;print-color-adjust:exact;overflow:hidden;
        }
        .tag-v .field{text-align:center;line-height:1.25;width:100%;padding:0 0.5mm}

        /* 横版 tag */
        .tag-h{
            display:flex;flex-direction:row;align-items:center;justify-content:center;
            gap:1mm;padding:0 1mm;
            -webkit-print-color-adjust:exact;print-color-adjust:exact;overflow:hidden;
        }
        .tag-h .field{white-space:nowrap;line-height:1;text-align:center}

        .cut-hint{text-align:center;color:#bbb;font-size:11px;padding:1mm 0 0}
        @media print{
            .controls,.cut-hint{display:none!important}
            body{background:#fff}
        }
    </style>
</head>
<body>

<div class="controls">
    <!-- Row 1:基本 -->
    <div class="row">
        <span class="row-title">姓名贴</span>
        <div class="divider"></div>
        <label>姓名:</label>
        <input type="text" class="inp-name" id="nameInput" value="搁得平" oninput="render()">
        <div class="divider"></div>
        <label>图标:</label>
        <div class="preset-icons" id="presetIcons"></div>
        <input type="text" id="customIconInput" placeholder="自选" onkeydown="if(event.key==='Enter')addCustomIcon()">
        <div class="btn btn-sm btn-upload">上传<input type="file" accept="image/*" multiple onchange="handleFileUpload(this)"></div>
        <div class="divider"></div>
        <div class="queue-area">
            <div class="queue-items" id="queueItems"></div>
            <button class="btn btn-sm btn-clear" onclick="clearQueue()">清空</button>
        </div>
    </div>

    <!-- Row 2:图标模式 + 边框 + 布局 -->
    <div class="row">
        <label>图标:</label>
        <div class="mode-group">
            <button class="mode-btn active" onclick="setMode('cycle',this)">循环</button>
            <button class="mode-btn" onclick="setMode('same',this)">统一</button>
            <button class="mode-btn" onclick="setMode('none',this)">无</button>
        </div>
        <div class="divider"></div>
        <label>布局:</label>
        <div class="mode-group">
            <button class="mode-btn active" id="btnV" onclick="setLayout('v',this)">竖版</button>
            <button class="mode-btn" id="btnH" onclick="setLayout('h',this)">横版</button>
        </div>
        <div class="divider"></div>
        <label>边框:</label>
        <select id="borderSelect" onchange="render()">
            <option value="0.3mm dashed #bbb">虚线</option>
            <option value="0.3mm solid #ccc">实线</option>
            <option value="0.3mm dotted #ccc">点线</option>
            <option value="none">无边框</option>
        </select>
        <div class="divider"></div>
        <label>标签底色:</label>
        <input type="color" id="tagBgColor" value="#ffffff" oninput="render()">
        <div class="color-reset" onclick="document.getElementById('tagBgColor').value='#ffffff';render()">✕</div>
        <button class="btn btn-print" onclick="window.print()">打印 Ctrl+P</button>
    </div>

    <!-- Row 3:每字段 字体 + 字号滑块 + 加粗 + 颜色 -->
    <div class="row">
        <label>图标:</label>
        <select class="field-font-select" id="fontIcon" onchange="render()"><option>图标不需要字体</option></select>
        <input type="range" class="slider-size" id="slIcon" min="5" max="20" step="0.5" value="10" oninput="render()">
        <span class="pt-badge" id="vIcon">10pt</span>
        <div class="divider"></div>
        <label>姓名:</label>
        <select class="field-font-select" id="fontName" onchange="render()"></select>
        <input type="range" class="slider-size" id="slName" min="6" max="24" step="0.5" value="13" oninput="render()">
        <span class="pt-badge" id="vName">13pt</span>
        <div class="bold-btn active" id="bName" onclick="toggleBold('Name')">B</div>
    </div>
    <div class="row">
        <span class="label-sm">颜色(文字/背景):</span>
        <div class="color-group">
            <label>姓名</label>
            <input type="color" id="cNameT" value="#111111" oninput="render()">
            <input type="color" id="cNameB" value="#ffffff" oninput="render()">
            <div class="color-reset" onclick="resetFC('Name')">✕</div>
        </div>
        <div class="color-group">
            <label>标签底色</label>
            <input type="color" id="tagBgColor2" value="#ffffff" oninput="syncTagBg()">
            <div class="color-reset" onclick="document.getElementById('tagBgColor').value='#ffffff';document.getElementById('tagBgColor2').value='#ffffff';render()">✕</div>
        </div>
        <div class="divider"></div>
        <span class="hint">左侧=文字色 右侧=背景色 · 白色背景自动透明</span>
    </div>

    <!-- Row 4:标签尺寸 + 网格 -->
    <div class="row">
        <label>宽度:</label>
        <input type="range" class="slider-tag" id="wSlider" min="20" max="150" step="1" value="40" oninput="render()">
        <span class="pt-badge" id="vW">40mm</span>
        <div class="divider"></div>
        <label>高度:</label>
        <input type="range" class="slider-tag" id="hSlider" min="15" max="120" step="1" value="60" oninput="render()">
        <span class="pt-badge" id="vH">60mm</span>
        <div class="divider"></div>
        <span class="grid-info" id="gridInfo">--</span>
        <div class="divider"></div>
        <span class="hint">A4纸 · 100%缩放 · 最小边距 · 取消页眉页脚</span>
    </div>
</div>

<div class="cut-hint" id="cutHint">⬆ 沿边框裁剪 · 图标在上、名字竖排 ⬆</div>
<div class="page-wrap"><div class="grid" id="grid"></div></div>

<script>
var PW=192,PH=285;
var layout='v'; // 'v'=竖版 'h'=横版
var iconMode='cycle';
var boldState={Name:true};
var iconQueue=[];

var FONT_OPTIONS=[
    ["'Microsoft YaHei','PingFang SC',sans-serif","微软雅黑"],
    ["'SimHei','Microsoft YaHei',sans-serif","黑体"],
    ["'SimSun','Songti SC',serif","宋体"],
    ["'KaiTi','STKaiti','Kaiti SC',serif","楷体"],
    ["'FangSong','STFangsong',serif","仿宋"],
    ["'Noto Sans SC',sans-serif","思源黑体"],
    ["'Noto Serif SC',serif","思源宋体"],
    ["'ZCOOL XiaoWei',serif","站酷小薇"],
    ["'Ma Shan Zheng',cursive","马善政楷"],
    ["'ZCOOL QingKe HuangYou',sans-serif","站酷庆科黄油"],
    ["'Long Cang',cursive","龙藏体"],
    ["'Zhi Mang Xing',cursive","志莽行书"]
];

var PRESETS=['🍑','🍉','🐲','🍒','🥑','⭐','🏷️','🌸','🍀','🐻','🎀','❤️','🌻','🎵','🍓','🐼','🌈','☀️','🦋','🍭'];

/* 初始化 */
(function(){
    /* 预设图标 */
    var box=document.getElementById('presetIcons');
    PRESETS.forEach(function(e){
        var d=document.createElement('div');d.className='preset-btn';d.textContent=e;
        d.onclick=function(){addToQueue(e);};box.appendChild(d);
    });
    ['🍑','🍉','🐲','🍒','🥑','⭐','🏷️'].forEach(function(e){iconQueue.push(e);});

    /* 字体下拉 */
    var sel=document.getElementById('fontName');sel.innerHTML='';
    FONT_OPTIONS.forEach(function(f,i){
        var o=document.createElement('option');o.value=f[0];o.textContent=f[1];
        if(i===0)o.selected=true;sel.appendChild(o);
    });

    updateQ();render();
})();

/* 布局切换 */
function setLayout(l,btn){
    layout=l;
    document.getElementById('btnV').classList.toggle('active',l==='v');
    document.getElementById('btnH').classList.toggle('active',l==='h');
    document.getElementById('cutHint').textContent=
        l==='v'?'⬆ 沿边框裁剪 · 图标在上、名字竖排 ⬆':'⬆ 沿边框裁剪 · 图标在左、名字横排 ⬆';
    render();
}

/* 模式 */
function setMode(m,btn){
    iconMode=m;
    document.querySelectorAll('.mode-group .mode-btn').forEach(function(b){
        if(b.parentElement===btn.parentElement)b.classList.remove('active');
    });
    btn.classList.add('active');render();
}

/* 加粗 */
function toggleBold(k){
    boldState[k]=!boldState[k];
    document.getElementById('b'+k).classList.toggle('active',boldState[k]);
    render();
}

/* 颜色重置 */
function resetFC(f){
    document.getElementById('c'+f+'T').value='#111111';
    document.getElementById('c'+f+'B').value='#ffffff';
    render();
}
function syncTagBg(){
    var v=document.getElementById('tagBgColor2').value;
    document.getElementById('tagBgColor').value=v;
    document.getElementById('tagBgColor').dispatchEvent(new Event('input'));
}

/* 图标队列 */
function addToQueue(icon){iconQueue.push(icon);updateQ();render();}
function addCustomIcon(){
    var v=document.getElementById('customIconInput').value.trim();
    if(!v)return;iconQueue.push(v);
    document.getElementById('customIconInput').value='';updateQ();render();
}
function handleFileUpload(inp){
    var fs=inp.files;if(!fs)return;
    for(var i=0;i<fs.length;i++){
        (function(f){
            var r=new FileReader();
            r.onload=function(e){iconQueue.push({t:'img',s:e.target.result});updateQ();render();};
            r.readAsDataURL(f);
        })(fs[i]);
    }
    inp.value='';
}
function removeFromQueue(i){iconQueue.splice(i,1);updateQ();render();}
function clearQueue(){iconQueue=[];updateQ();render();}
function updateQ(){
    var c=document.getElementById('queueItems');
    if(!iconQueue.length){c.innerHTML='<span class="queue-empty">无图标</span>';return;}
    var h='';
    iconQueue.forEach(function(it,i){
        h+='<span class="queue-tag" onclick="removeFromQueue('+i+')" title="点击移除">';
        if(typeof it==='string')h+=it;
        else if(it&&it.t==='img')h+='<img src="'+it.s+'">';
        h+='<span class="rm">✕</span></span>';
    });
    c.innerHTML=h;
}
function getIcon(idx){
    if(!iconQueue.length||iconMode==='none')return null;
    if(iconMode==='same')return iconQueue[0];
    return iconQueue[idx%iconQueue.length];
}

/* 工具 */
function bgC(id){var v=document.getElementById(id).value;return v.toLowerCase()==='#ffffff'?'transparent':v;}

/* 主渲染 */
function render(){
    var name=document.getElementById('nameInput').value.trim()||'姓名';
    var ffN=document.getElementById('fontName').value;
    var bd=document.getElementById('borderSelect').value;

    var is=parseFloat(document.getElementById('slIcon').value)||10;
    var nfs=parseFloat(document.getElementById('slName').value)||13;
    document.getElementById('vIcon').textContent=is+'pt';
    document.getElementById('vName').textContent=nfs+'pt';
    var bwN=boldState.Name?'700':'400';

    var cNT=document.getElementById('cNameT').value;
    var cNB=bgC('cNameB');
    var tagBg=bgC('tagBgColor');
    document.getElementById('tagBgColor2').value=document.getElementById('tagBgColor').value;

    var tw=Math.max(15,Math.min(150,parseFloat(document.getElementById('wSlider').value)||40));
    var th=Math.max(15,Math.min(120,parseFloat(document.getElementById('hSlider').value)||60));
    document.getElementById('vW').textContent=tw+'mm';
    document.getElementById('vH').textContent=th+'mm';

    var cols=Math.max(1,Math.floor(PW/tw));
    var rows=Math.max(1,Math.floor(PH/th));
    var total=cols*rows;
    document.getElementById('gridInfo').textContent=cols+'列×'+rows+'行='+total+'张';

    var g=document.getElementById('grid');
    g.style.gridTemplateColumns='repeat('+cols+','+tw+'mm)';
    g.style.gridTemplateRows='repeat('+rows+','+th+'mm)';
    g.innerHTML='';

    for(var i=0;i<total;i++){
        var tag=document.createElement('div');
        tag.className=layout==='v'?'tag-v':'tag-h';
        tag.style.border=bd;
        if(tagBg!=='transparent')tag.style.background=tagBg;

        /* 图标 */
        var icon=getIcon(i);
        if(icon){
            var ic=document.createElement('span');
            ic.className='field';
            ic.style.fontSize=is+'pt';
            if(typeof icon==='string'){
                ic.textContent=icon;
            }else if(icon&&icon.t==='img'){
                var img=document.createElement('img');
                img.src=icon.s;
                var ims=Math.min(th*0.5,tw*0.3,is*0.42);
                img.style.width=ims+'mm';img.style.height=ims+'mm';
                ic.appendChild(img);
            }
            tag.appendChild(ic);
        }

        /* 姓名 */
        var nd=document.createElement('div');
        nd.className='field';nd.textContent=name;
        nd.style.fontFamily=ffN;nd.style.fontSize=nfs+'pt';
        nd.style.fontWeight=bwN;nd.style.color=cNT;
        nd.style.letterSpacing='0.06em';
        if(cNB!=='transparent')nd.style.background=cNB;
        tag.appendChild(nd);

        g.appendChild(tag);
    }
}

render();
</script>

</body>
</html>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名贴生成器</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Long+Cang&family=Ma+Shan+Zheng&family=ZCOOL+QingKe+HuangYou&family=ZCOOL+XiaoWei&family=Zhi+Mang+Xing&family=Noto+Sans+SC:wght@300;400;500;700&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
    <style>
        @page{size:A4 portrait;margin:6mm 9mm}
        *{margin:0;padding:0;box-sizing:border-box}
        body{font-family:"Microsoft YaHei","PingFang SC",sans-serif;background:#f5f2ec}

        .controls{
            position:sticky;top:0;z-index:100;
            padding:12px 20px 8px;
            background:linear-gradient(145deg,#1a1a1a 0%,#252018 100%);
            color:#ddd8ce;font-size:13px;
            box-shadow:0 4px 24px rgba(0,0,0,0.3);border-bottom:1px solid #3a3530;
        }
        .row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:7px}
        .row:last-child{margin-bottom:0}
        .row-title{font-size:17px;font-weight:700;color:#fff;letter-spacing:0.06em}
        .divider{width:1px;height:18px;background:#4a4540;flex-shrink:0}
        label{font-weight:500;white-space:nowrap;font-size:12px;color:#bbb5a8}
        .label-sm{font-size:11px;color:#999;white-space:nowrap}

        input[type="text"],select{
            padding:5px 8px;font-size:13px;border:1px solid #555;
            border-radius:5px;background:#2e2e2e;color:#eee;outline:none;transition:border-color .2s;
        }
        input[type="text"]:focus,select:focus{border-color:#c8a951}
        select{cursor:pointer}
        .inp-name{width:78px}.inp-class{width:68px}.inp-num{width:42px}.inp-add-subj{width:60px}

        input[type="range"]{
            -webkit-appearance:none;height:5px;border-radius:3px;background:#444;outline:none;cursor:pointer;
        }
        input[type="range"]::-webkit-slider-thumb{
            -webkit-appearance:none;width:15px;height:15px;border-radius:50%;
            background:#c8a951;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,0.3);
            transition:transform .15s;
        }
        input[type="range"]::-webkit-slider-thumb:hover{transform:scale(1.15)}
        .slider-size{width:56px}.slider-tag{width:82px}

        .pt-badge{
            display:inline-block;min-width:28px;text-align:center;
            padding:1px 5px;border-radius:3px;font-size:11px;
            font-weight:600;color:#c8a951;background:#2a2520;
        }
        .grid-info{
            font-size:12px;color:#c8a951;font-weight:600;
            background:#2a2520;padding:3px 10px;border-radius:4px;white-space:nowrap;
        }

        .bold-btn{
            width:26px;height:26px;display:flex;align-items:center;justify-content:center;
            border:2px solid #555;border-radius:4px;cursor:pointer;
            font-size:13px;font-weight:900;background:#2e2a26;color:#888;
            transition:all .15s;user-select:none;
        }
        .bold-btn:hover{border-color:#999;color:#bbb}
        .bold-btn.active{border-color:#c8a951;color:#c8a951;background:#332e22}

        .field-font-select{
            padding:4px 4px;font-size:11px;border:1px solid #444;
            border-radius:4px;background:#2a2a2a;color:#ccc;cursor:pointer;max-width:110px;
        }

        /* 颜色选择器 */
        input[type="color"]{
            -webkit-appearance:none;border:2px solid #555;border-radius:4px;
            width:26px;height:26px;padding:0;cursor:pointer;background:#2a2a2a;
            transition:border-color .15s;
        }
        input[type="color"]:hover{border-color:#c8a951}
        input[type="color"]::-webkit-color-swatch-wrapper{padding:1px}
        input[type="color"]::-webkit-color-swatch{border-radius:2px;border:none}

        .color-group{
            display:inline-flex;align-items:center;gap:3px;
            padding:2px 6px;background:#252220;border-radius:4px;
        }
        .color-reset{
            width:18px;height:18px;display:flex;align-items:center;justify-content:center;
            font-size:10px;color:#777;cursor:pointer;border-radius:2px;
            background:transparent;border:1px solid #444;transition:all .15s;
        }
        .color-reset:hover{color:#e88;border-color:#888;background:#3a2a2a}

        .btn{padding:6px 14px;border:none;border-radius:5px;cursor:pointer;font-size:12px;font-weight:600;transition:all .2s}
        .btn-sm{padding:4px 10px;font-size:11px}
        .btn-add{background:#4a6e3a;color:#c8e0b4}.btn-add:hover{background:#5a8248}
        .btn-print{background:#c8a951;color:#1a1a1a;font-size:13px;padding:6px 18px}
        .btn-print:hover{background:#d4b85e;transform:translateY(-1px)}
        .hint{font-size:10px;color:#666}
        .tip{font-size:10.5px;color:#c8a951}

        /* 学科标签 */
        .subj-tags{
            display:flex;align-items:center;gap:4px;flex-wrap:wrap;
            padding:4px 8px;background:#242220;border-radius:5px;border:1px solid #3a3835;
            min-height:30px;min-width:80px;
        }
        .subj-tag{
            display:inline-flex;align-items:center;gap:3px;
            padding:3px 8px;border-radius:4px;font-size:12px;
            cursor:pointer;transition:all .15s;font-weight:500;
        }
        .subj-tag .st-rm{font-size:9px;opacity:0.5;margin-left:2px}
        .subj-tag:hover .st-rm{opacity:1}
        .subj-tag.c0{background:#2a3a2a;color:#8bc48b}
        .subj-tag.c1{background:#2a2a3a;color:#8ba8c4}
        .subj-tag.c2{background:#3a2a2a;color:#c48b8b}
        .subj-tag.c3{background:#3a3a2a;color:#c4c48b}
        .subj-tag.c4{background:#3a2a3a;color:#c48bc4}
        .subj-tag.c5{background:#2a3a3a;color:#8bc4c4}
        .subj-tag.c6{background:#332a2a;color:#c4a88b}
        .subj-tag.c7{background:#2a332a;color:#8bc49b}
        .subj-empty{color:#666;font-size:11px;font-style:italic}

        /* 预览 */
        .preview-field{
            display:flex;align-items:center;gap:4px;
            padding:4px 10px;border-radius:4px;
        }
        .preview-field .pf-label{font-size:10px;color:#777;white-space:nowrap}
        .preview-field .pf-sample{white-space:nowrap;line-height:1}

        /* 网格 */
        .page-wrap{padding:3mm 0 10mm;display:flex;justify-content:center}
        .grid{display:grid;justify-content:center;align-content:start}
        .tag{
            display:flex;flex-direction:column;align-items:center;justify-content:space-around;
            padding:1.5mm 1mm;
            -webkit-print-color-adjust:exact;print-color-adjust:exact;overflow:hidden;
        }
        .tag .field{text-align:center;line-height:1.25;width:100%;padding:1px 0.5mm;border-radius:1px}
        .tag .field.subj{
            cursor:pointer;border-bottom:0.3mm dashed #ccc;
            padding-bottom:0.5mm;transition:background .15s;
        }
        .tag .field.subj:hover{background:rgba(200,169,81,0.12)!important}
        .tag .field.subj input.inline-edit{
            width:88%;text-align:center;border:1px solid #c8a951;border-radius:2px;
            padding:1px 3px;outline:none;background:#fff;color:#111;
        }
        .cut-hint{text-align:center;color:#bbb;font-size:11px;padding:1mm 0 0}
        @media print{
            .controls,.cut-hint{display:none!important}
            body{background:#fff}
            .tag .field.subj{cursor:default!important;border-bottom:none!important}
            .tag .field.subj:hover{background:transparent!important}
        }
    </style>
</head>
<body>

<div class="controls">
    <!-- Row 1:基本 -->
    <div class="row">
        <span class="row-title">姓名贴</span>
        <div class="divider"></div>
        <label>姓名:</label>
        <input type="text" class="inp-name" id="nameInput" value="搁得平" oninput="render()">
        <div class="divider"></div>
        <label>班级:</label>
        <input type="text" class="inp-class" id="classInput" value="一(二)班" oninput="render()">
        <div class="divider"></div>
        <label>学号:</label>
        <input type="text" class="inp-num" id="numInput" value="41" oninput="render()">
        <div class="divider"></div>
        <label>边框:</label>
        <select id="borderSelect" onchange="render()">
            <option value="0.3mm dashed #bbb">虚线</option>
            <option value="0.3mm solid #ccc">实线</option>
            <option value="0.3mm dotted #ccc">点线</option>
            <option value="none">无边框</option>
        </select>
        <div class="divider"></div>
        <label>标签底色:</label>
        <input type="color" id="tagBgColor" value="#ffffff" oninput="render()" title="标签背景色">
        <div class="color-reset" onclick="resetColor('tagBgColor','#ffffff');render()" title="重置">✕</div>
        <button class="btn btn-print" onclick="window.print()">打印 Ctrl+P</button>
    </div>

    <!-- Row 2:学科列表 -->
    <div class="row">
        <label>学科列表:</label>
        <div class="subj-tags" id="subjTags"></div>
        <input type="text" class="inp-add-subj" id="addSubjInput" placeholder="输入学科"
               onkeydown="if(event.key==='Enter')addSubj()">
        <button class="btn btn-sm btn-add" onclick="addSubj()">添加</button>
        <div class="divider"></div>
        <span class="hint">多学科循环分配 · 点标签学科可单独改</span>
    </div>

    <!-- Row 3:字体 + 字号 + 加粗 -->
    <div class="row">
        <label>学科:</label>
        <select class="field-font-select" id="fontSubj" onchange="render()"></select>
        <input type="range" class="slider-size" id="sliderSubj" min="5" max="20" step="0.5" value="9" oninput="render()">
        <span class="pt-badge" id="valSubj">9pt</span>
        <div class="bold-btn" id="boldSubj" onclick="toggleBold('Subj')" title="加粗">B</div>
        <div class="divider"></div>
        <label>姓名:</label>
        <select class="field-font-select" id="fontName" onchange="render()"></select>
        <input type="range" class="slider-size" id="sliderName" min="6" max="24" step="0.5" value="14" oninput="render()">
        <span class="pt-badge" id="valName">14pt</span>
        <div class="bold-btn active" id="boldName" onclick="toggleBold('Name')" title="加粗">B</div>
        <div class="divider"></div>
        <label>班级:</label>
        <select class="field-font-select" id="fontClass" onchange="render()"></select>
        <input type="range" class="slider-size" id="sliderClass" min="5" max="20" step="0.5" value="9" oninput="render()">
        <span class="pt-badge" id="valClass">9pt</span>
        <div class="bold-btn" id="boldClass" onclick="toggleBold('Class')" title="加粗">B</div>
        <div class="divider"></div>
        <label>学号:</label>
        <select class="field-font-select" id="fontNum" onchange="render()"></select>
        <input type="range" class="slider-size" id="sliderNum" min="5" max="22" step="0.5" value="12" oninput="render()">
        <span class="pt-badge" id="valNum">12pt</span>
        <div class="bold-btn active" id="boldNum" onclick="toggleBold('Num')" title="加粗">B</div>
    </div>

    <!-- Row 4:颜色 -->
    <div class="row">
        <span class="label-sm" style="margin-right:4px">颜色(文字 / 背景):</span>
        <div class="color-group">
            <label>学科</label>
            <input type="color" id="clrSubjText" value="#111111" oninput="render()">
            <input type="color" id="clrSubjBg" value="#ffffff" oninput="render()">
            <div class="color-reset" onclick="resetFieldColor('Subj');render()" title="重置">✕</div>
        </div>
        <div class="color-group">
            <label>姓名</label>
            <input type="color" id="clrNameText" value="#111111" oninput="render()">
            <input type="color" id="clrNameBg" value="#ffffff" oninput="render()">
            <div class="color-reset" onclick="resetFieldColor('Name');render()" title="重置">✕</div>
        </div>
        <div class="color-group">
            <label>班级</label>
            <input type="color" id="clrClassText" value="#111111" oninput="render()">
            <input type="color" id="clrClassBg" value="#ffffff" oninput="render()">
            <div class="color-reset" onclick="resetFieldColor('Class');render()" title="重置">✕</div>
        </div>
        <div class="color-group">
            <label>学号</label>
            <input type="color" id="clrNumText" value="#111111" oninput="render()">
            <input type="color" id="clrNumBg" value="#ffffff" oninput="render()">
            <div class="color-reset" onclick="resetFieldColor('Num');render()" title="重置">✕</div>
        </div>
        <div class="divider"></div>
        <span class="hint">左侧=文字色 右侧=背景色</span>
    </div>

    <!-- Row 5:预览 + 尺寸 -->
    <div class="row">
        <span class="label-sm">预览:</span>
        <div class="preview-field" id="pvBoxSubj"><span class="pf-label">学科</span><span class="pf-sample" id="pvSubj">语文</span></div>
        <div class="preview-field" id="pvBoxName"><span class="pf-label">姓名</span><span class="pf-sample" id="pvName">搁得平</span></div>
        <div class="preview-field" id="pvBoxClass"><span class="pf-label">班级</span><span class="pf-sample" id="pvClass">一(二)班</span></div>
        <div class="preview-field" id="pvBoxNum"><span class="pf-label">学号</span><span class="pf-sample" id="pvNum">41</span></div>
        <div class="divider"></div>
        <label>宽:</label>
        <input type="range" class="slider-tag" id="wSlider" min="20" max="120" step="1" value="36" oninput="render()">
        <span class="pt-badge" id="valW">36mm</span>
        <div class="divider"></div>
        <label>高:</label>
        <input type="range" class="slider-tag" id="hSlider" min="20" max="120" step="1" value="52" oninput="render()">
        <span class="pt-badge" id="valH">52mm</span>
        <div class="divider"></div>
        <span class="grid-info" id="gridInfo">--</span>
        <div class="divider"></div>
        <span class="tip" id="customTip"></span>
    </div>
</div>

<div class="cut-hint">⬆ 沿边框裁剪 · 学科按列表循环 · 点击标签学科可单独改 · 颜色实时预览 ⬆</div>
<div class="page-wrap"><div class="grid" id="grid"></div></div>

<script>
var PW=192,PH=285;
var boldState={Subj:false,Name:true,Class:false,Num:true};
var subjList=['语文','数学','英语'];
var subjOverride={};

var FONT_OPTIONS=[
    ["'Microsoft YaHei','PingFang SC',sans-serif","微软雅黑"],
    ["'SimHei','Microsoft YaHei',sans-serif","黑体"],
    ["'SimSun','Songti SC',serif","宋体"],
    ["'KaiTi','STKaiti','Kaiti SC',serif","楷体"],
    ["'FangSong','STFangsong',serif","仿宋"],
    ["'Noto Sans SC',sans-serif","思源黑体"],
    ["'Noto Serif SC',serif","思源宋体"],
    ["'ZCOOL XiaoWei',serif","站酷小薇"],
    ["'Ma Shan Zheng',cursive","马善政楷"],
    ["'ZCOOL QingKe HuangYou',sans-serif","站酷庆科黄油"],
    ["'Long Cang',cursive","龙藏体"],
    ["'Zhi Mang Xing',cursive","志莽行书"]
];

var DEFAULT_COLORS={
    SubjText:'#111111',SubjBg:'#ffffff',
    NameText:'#111111',NameBg:'#ffffff',
    ClassText:'#111111',ClassBg:'#ffffff',
    NumText:'#111111',NumBg:'#ffffff',
    TagBg:'#ffffff'
};

function initFontSelects(){
    ['fontSubj','fontName','fontClass','fontNum'].forEach(function(id){
        var sel=document.getElementById(id);sel.innerHTML='';
        FONT_OPTIONS.forEach(function(f,i){
            var o=document.createElement('option');
            o.value=f[0];o.textContent=f[1];
            if(i===0)o.selected=true;
            sel.appendChild(o);
        });
    });
}

function toggleBold(key){
    boldState[key]=!boldState[key];
    document.getElementById('bold'+key).classList.toggle('active',boldState[key]);
    render();
}

function resetColor(id,def){document.getElementById(id).value=def}

function resetFieldColor(f){
    document.getElementById('clr'+f+'Text').value=DEFAULT_COLORS[f+'Text'];
    document.getElementById('clr'+f+'Bg').value=DEFAULT_COLORS[f+'Bg'];
}

/* 学科列表管理 */
function updateSubjTags(){
    var box=document.getElementById('subjTags');
    if(!subjList.length){box.innerHTML='<span class="subj-empty">暂无学科</span>';return}
    var h='';
    subjList.forEach(function(s,i){
        h+='<span class="subj-tag c'+(i%8)+'" onclick="removeSubj('+i+')" title="点击删除">'
            +s+'<span class="st-rm">✕</span></span>';
    });
    box.innerHTML=h;
}
function addSubj(){
    var inp=document.getElementById('addSubjInput'),v=inp.value.trim();
    if(!v)return;subjList.push(v);inp.value='';
    subjOverride={};updateSubjTags();render();
}
function removeSubj(i){
    subjList.splice(i,1);subjOverride={};updateSubjTags();render();
}
function getSubjFor(idx){
    if(subjOverride[idx]!==undefined)return subjOverride[idx];
    if(!subjList.length)return'';
    return subjList[idx%subjList.length];
}

/* 点击标签编辑学科 */
function editSubjOnTag(idx,el){
    var cur=getSubjFor(idx);
    el.innerHTML='';
    var inp=document.createElement('input');
    inp.type='text';inp.className='inline-edit';inp.value=cur;
    inp.style.fontSize=(parseFloat(document.getElementById('sliderSubj').value)||9)+'pt';
    inp.style.fontFamily=document.getElementById('fontSubj').value;
    inp.style.fontWeight=boldState.Subj?'700':'400';
    inp.style.color=document.getElementById('clrSubjText').value;
    inp.onblur=function(){
        var v=this.value.trim();
        var def=subjList.length?subjList[idx%subjList.length]:'';
        if(v&&v!==def)subjOverride[idx]=v;
        else delete subjOverride[idx];
        render();
    };
    inp.onkeydown=function(e){if(e.key==='Enter')this.blur();if(e.key==='Escape')this.blur()};
    el.appendChild(inp);inp.focus();inp.select();
}

/* 获取颜色(白色背景视为透明) */
function bgColor(id){
    var v=document.getElementById(id).value;
    return v.toLowerCase()==='#ffffff'?'transparent':v;
}

/* 主渲染 */
function render(){
    var name=document.getElementById('nameInput').value.trim()||'姓名';
    var cls=document.getElementById('classInput').value.trim();
    var num=document.getElementById('numInput').value.trim();
    var bd=document.getElementById('borderSelect').value;

    var ffS=document.getElementById('fontSubj').value;
    var ffN=document.getElementById('fontName').value;
    var ffC=document.getElementById('fontClass').value;
    var ffX=document.getElementById('fontNum').value;

    var sfs=parseFloat(document.getElementById('sliderSubj').value)||9;
    var nfs=parseFloat(document.getElementById('sliderName').value)||14;
    var cfs=parseFloat(document.getElementById('sliderClass').value)||9;
    var numfs=parseFloat(document.getElementById('sliderNum').value)||12;

    document.getElementById('valSubj').textContent=sfs+'pt';
    document.getElementById('valName').textContent=nfs+'pt';
    document.getElementById('valClass').textContent=cfs+'pt';
    document.getElementById('valNum').textContent=numfs+'pt';

    var bwS=boldState.Subj?'700':'400';
    var bwN=boldState.Name?'700':'400';
    var bwC=boldState.Class?'700':'400';
    var bwX=boldState.Num?'700':'400';

    /* 颜色 */
    var cST=document.getElementById('clrSubjText').value;
    var cSB=bgColor('clrSubjBg');
    var cNT=document.getElementById('clrNameText').value;
    var cNB=bgColor('clrNameBg');
    var cCT=document.getElementById('clrClassText').value;
    var cCB=bgColor('clrClassBg');
    var cXT=document.getElementById('clrNumText').value;
    var cXB=bgColor('clrNumBg');
    var tagBg=bgColor('tagBgColor');

    /* 标签尺寸 */
    var tw=Math.max(15,Math.min(150,parseFloat(document.getElementById('wSlider').value)||36));
    var th=Math.max(15,Math.min(150,parseFloat(document.getElementById('hSlider').value)||52));
    document.getElementById('valW').textContent=tw+'mm';
    document.getElementById('valH').textContent=th+'mm';

    var cols=Math.max(1,Math.floor(PW/tw));
    var rows=Math.max(1,Math.floor(PH/th));
    var total=cols*rows;
    document.getElementById('gridInfo').textContent=cols+'列×'+rows+'行='+total+'张';

    var ov=Object.keys(subjOverride).length;
    document.getElementById('customTip').textContent=ov?'单独改'+ov+'张':'';

    /* 预览 */
    var pv0=subjList.length?subjList[0]:'—';
    var pv=document.getElementById('pvSubj');
    pv.textContent=pv0;pv.style.fontFamily=ffS;pv.style.fontSize=sfs+'pt';pv.style.fontWeight=bwS;pv.style.color=cST;
    document.getElementById('pvBoxSubj').style.background=cSB;

    var pn=document.getElementById('pvName');
    pn.textContent=name;pn.style.fontFamily=ffN;pn.style.fontSize=nfs+'pt';pn.style.fontWeight=bwN;pn.style.color=cNT;
    document.getElementById('pvBoxName').style.background=cNB;

    var pc=document.getElementById('pvClass');
    pc.textContent=cls||'—';pc.style.fontFamily=ffC;pc.style.fontSize=cfs+'pt';pc.style.fontWeight=bwC;pc.style.color=cCT;
    document.getElementById('pvBoxClass').style.background=cCB;

    var px=document.getElementById('pvNum');
    px.textContent=num||'—';px.style.fontFamily=ffX;px.style.fontSize=numfs+'pt';px.style.fontWeight=bwX;px.style.color=cXT;
    document.getElementById('pvBoxNum').style.background=cXB;

    /* 网格 */
    var g=document.getElementById('grid');
    g.style.gridTemplateColumns='repeat('+cols+','+tw+'mm)';
    g.style.gridTemplateRows='repeat('+rows+','+th+'mm)';
    g.innerHTML='';

    for(var i=0;i<total;i++){
        var tag=document.createElement('div');
        tag.className='tag';tag.style.border=bd;
        if(tagBg!=='transparent')tag.style.background=tagBg;

        /* 学科 */
        var subjText=getSubjFor(i);
        if(subjText){
            var sd=document.createElement('div');
            sd.className='field subj';
            sd.textContent=subjText;
            sd.style.fontFamily=ffS;sd.style.fontSize=sfs+'pt';
            sd.style.fontWeight=bwS;sd.style.color=cST;
            if(cSB!=='transparent')sd.style.background=cSB;
            (function(idx){sd.onclick=function(e){e.stopPropagation();editSubjOnTag(idx,this)}})(i);
            tag.appendChild(sd);
        }

        /* 姓名 */
        var nd=document.createElement('div');
        nd.className='field';nd.textContent=name;
        nd.style.fontFamily=ffN;nd.style.fontSize=nfs+'pt';
        nd.style.fontWeight=bwN;nd.style.color=cNT;
        nd.style.letterSpacing='0.05em';
        if(cNB!=='transparent')nd.style.background=cNB;
        tag.appendChild(nd);

        /* 班级 */
        if(cls){
            var cd=document.createElement('div');
            cd.className='field';cd.textContent=cls;
            cd.style.fontFamily=ffC;cd.style.fontSize=cfs+'pt';
            cd.style.fontWeight=bwC;cd.style.color=cCT;
            if(cCB!=='transparent')cd.style.background=cCB;
            tag.appendChild(cd);
        }

        /* 学号 */
        if(num){
            var xd=document.createElement('div');
            xd.className='field';xd.textContent=num;
            xd.style.fontFamily=ffX;xd.style.fontSize=numfs+'pt';
            xd.style.fontWeight=bwX;xd.style.color=cXT;
            if(cXB!=='transparent')xd.style.background=cXB;
            tag.appendChild(xd);
        }

        g.appendChild(tag);
    }
}

initFontSelects();
updateSubjTags();
render();
</script>

</body>
</html>

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
irundream + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| 遇见你 发表于 2026-8-31 18:10 |楼主
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名贴生成器 · 横版</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Long+Cang&family=Ma+Shan+Zheng&family=ZCOOL+QingKe+HuangYou&family=ZCOOL+XiaoWei&family=Zhi+Mang+Xing&family=Noto+Sans+SC:wght@300;400;500;700&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
    <style>
        [url=home.php?mod=space&uid=1953840]@page[/url] { size: A4 portrait; margin: 6mm 9mm; }
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: "Microsoft YaHei","PingFang SC",sans-serif;
            background: #f5f2ec;
        }

        /* ===== 控制面板 ===== */
        .controls {
            position: sticky; top: 0; z-index: 100;
            padding: 14px 22px 10px;
            background: linear-gradient(145deg, #1a1a1a 0%, #252018 100%);
            color: #ddd8ce;
            font-size: 13px;
            box-shadow: 0 4px 24px rgba(0,0,0,0.3);
            border-bottom: 1px solid #3a3530;
        }
        .row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:9px; }
        .row:last-child { margin-bottom:0; }
        .row-title { font-size:17px; font-weight:700; color:#fff; letter-spacing:0.08em; }
        .divider { width:1px; height:18px; background:#4a4540; flex-shrink:0; }
        label { font-weight:500; white-space:nowrap; font-size:12px; color:#bbb5a8; }

        input[type="text"], select {
            padding:5px 8px; font-size:13px; border:1px solid #555;
            border-radius:5px; background:#2e2e2e; color:#eee; outline:none;
            transition:border-color 0.2s;
        }
        input[type="text"]:focus, select:focus { border-color:#c8a951; }
        select { cursor:pointer; }
        #nameInput { width:80px; }
        #fontSizeInput { width:40px; text-align:center; }
        #iconSizeInput { width:40px; text-align:center; }
        #customIconInput { width:52px; text-align:center; font-size:16px; }
        #widthInput, #heightInput { width:48px; text-align:center; }

        input[type="range"] {
            -webkit-appearance:none; height:4px; border-radius:2px;
            background:#555; outline:none; cursor:pointer; width:90px;
        }
        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance:none; width:14px; height:14px;
            border-radius:50%; background:#c8a951; cursor:pointer;
        }
        .size-group { display:flex; align-items:center; gap:5px; }

        .grid-info {
            font-size:12px; color:#c8a951; font-weight:600;
            white-space:nowrap; background:#2a2520; padding:3px 10px; border-radius:4px;
        }

        .btn {
            padding:6px 14px; border:none; border-radius:5px; cursor:pointer;
            font-size:12px; font-weight:600; transition:all 0.2s;
        }
        .btn-sm { padding:4px 10px; font-size:11px; }
        .btn-add { background:#4a6e3a; color:#c8e0b4; }
        .btn-add:hover { background:#5a8248; }
        .btn-clear { background:#5a3a3a; color:#e0b4b4; }
        .btn-clear:hover { background:#6e4848; }
        .btn-print { background:#c8a951; color:#1a1a1a; font-size:13px; padding:6px 18px; }
        .btn-print:hover { background:#d4b85e; transform:translateY(-1px); }
        .btn-upload { background:#3a5a6e; color:#b4d4e0; position:relative; overflow:hidden; }
        .btn-upload:hover { background:#4a6e82; }
        .btn-upload input[type="file"] {
            position:absolute; inset:0; opacity:0; cursor:pointer; font-size:0;
        }

        .preset-icons { display:flex; gap:3px; flex-wrap:wrap; }
        .preset-btn {
            width:28px; height:28px; display:flex; align-items:center; justify-content:center;
            border:2px solid #4a4540; border-radius:5px; cursor:pointer;
            font-size:15px; background:#2e2a26; transition:all 0.15s; user-select:none;
        }
        .preset-btn:hover { border-color:#c8a951; background:#3a3630; transform:scale(1.12); }

        .queue-area { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
        .queue-items {
            display:flex; gap:3px; align-items:center; flex-wrap:wrap;
            min-height:28px; padding:3px 7px; background:#242220;
            border-radius:5px; border:1px solid #3a3835;
            min-width:140px; max-width:50vw;
        }
        .queue-tag {
            display:inline-flex; align-items:center; gap:2px;
            padding:2px 5px; background:#333028; border-radius:4px;
            font-size:14px; cursor:pointer; transition:background 0.15s;
        }
        .queue-tag:hover { background:#5a3a3a; }
        .queue-tag img { width:16px; height:16px; object-fit:contain; border-radius:2px; }
        .queue-tag .rm { font-size:8px; color:#777; margin-left:1px; }
        .queue-tag:hover .rm { color:#e88; }
        .queue-empty { color:#666; font-size:11px; font-style:italic; }

        .mode-group { display:flex; border-radius:5px; overflow:hidden; border:1px solid #555; }
        .mode-btn {
            padding:4px 11px; font-size:11px; font-weight:500;
            cursor:pointer; background:#2e2e2e; color:#999; border:none; transition:all 0.2s;
        }
        .mode-btn.active { background:#c8a951; color:#1a1a1a; }
        .mode-btn:hover:not(.active) { background:#3a3a3a; }
        .hint { font-size:10px; color:#555; line-height:1.5; }

        /* ===== 标签网格 ===== */
        .page-wrap { padding:3mm 0 10mm; display:flex; justify-content:center; }
        .grid { display:grid; justify-content:center; align-content:start; }
        .tag {
            display:flex; flex-direction:row; align-items:center;
            justify-content:center; gap:2mm; padding:0 2mm;
            -webkit-print-color-adjust:exact; print-color-adjust:exact; overflow:hidden;
        }
        .tag .icon {
            flex-shrink:0; line-height:1; display:flex;
            align-items:center; justify-content:center;
        }
        .tag .icon img { object-fit:contain; display:block; }
        .tag .name-text {
            line-height:1; color:#1a1a1a; white-space:nowrap; letter-spacing:0.08em;
        }
        .cut-hint { text-align:center; color:#bbb; font-size:11px; padding:1mm 0 0; }
        @media print {
            .controls { display:none !important; }
            .cut-hint { display:none !important; }
            body { background:#fff; }
        }
    </style>
</head>
<body>

<div class="controls">
    <!-- Row 1 -->
    <div class="row">
        <span class="row-title">姓名贴 · 横版</span>
        <div class="divider"></div>
        <label>姓名:</label>
        <input type="text" id="nameInput" value="搁得平" maxlength="8"
               onkeydown="if(event.key==='Enter')render()">
        <div class="divider"></div>
        <label>字体:</label>
        <select id="fontSelect" onchange="render()">
            <option value="'Microsoft YaHei','PingFang SC',sans-serif">微软雅黑</option>
            <option value="'SimHei','Microsoft YaHei',sans-serif">黑体</option>
            <option value="'SimSun','Songti SC',serif">宋体</option>
            <option value="'KaiTi','STKaiti','Kaiti SC',serif">楷体</option>
            <option value="'FangSong','STFangsong',serif">仿宋</option>
            <option value="'Noto Sans SC',sans-serif">思源黑体</option>
            <option value="'Noto Serif SC',serif">思源宋体</option>
            <option value="'ZCOOL XiaoWei',serif">站酷小薇</option>
            <option value="'Ma Shan Zheng',cursive">马善政楷</option>
            <option value="'ZCOOL QingKe HuangYou',sans-serif">站酷庆科黄油</option>
            <option value="'Long Cang',cursive">龙藏体</option>
            <option value="'Zhi Mang Xing',cursive">志莽行书</option>
        </select>
        <div class="divider"></div>
        <label>字号:</label>
        <input type="text" id="fontSizeInput" value="13" maxlength="2"
               onkeydown="if(event.key==='Enter')render()"> pt
        <div class="divider"></div>
        <label>边框:</label>
        <select id="borderSelect" onchange="render()">
            <option value="0.3mm dashed #bbb">虚线</option>
            <option value="0.3mm solid #ccc">实线</option>
            <option value="0.3mm dotted #ccc">点线</option>
            <option value="none">无边框</option>
        </select>
        <div class="divider"></div>
        <div class="mode-group">
            <button class="mode-btn active" onclick="setMode('cycle',this)">循环</button>
            <button class="mode-btn" onclick="setMode('same',this)">统一</button>
            <button class="mode-btn" onclick="setMode('none',this)">无图标</button>
        </div>
        <button class="btn btn-print" onclick="window.print()">打印 Ctrl+P</button>
    </div>

    <!-- Row 2 -->
    <div class="row">
        <label>图标:</label>
        <div class="preset-icons" id="presetIcons"></div>
        <div class="divider"></div>
        <input type="text" id="customIconInput" placeholder="自定义"
               onkeydown="if(event.key==='Enter')addCustomIcon()">
        <button class="btn btn-sm btn-add" onclick="addCustomIcon()">添加</button>
        <div class="divider"></div>
        <div class="btn btn-sm btn-upload">
            上传图片
            <input type="file" accept="image/*" multiple onchange="handleFileUpload(this)">
        </div>
        <div class="divider"></div>
        <label>图标大小:</label>
        <input type="text" id="iconSizeInput" value="10" maxlength="2"
               onkeydown="if(event.key==='Enter')render()"> pt
    </div>

    <!-- Row 3:尺寸控制 -->
    <div class="row">
        <label>标签宽度:</label>
        <div class="size-group">
            <input type="range" id="widthSlider" min="25" max="120" step="1" value="50"
                   oninput="syncW(this.value)">
            <input type="text" id="widthInput" value="50"
                   onkeydown="if(event.key==='Enter'){syncW2();render()}"
                   onchange="syncW2();render()"> mm
        </div>
        <div class="divider"></div>
        <label>标签高度:</label>
        <div class="size-group">
            <input type="range" id="heightSlider" min="8" max="50" step="1" value="15"
                   oninput="syncH(this.value)">
            <input type="text" id="heightInput" value="15"
                   onkeydown="if(event.key==='Enter'){syncH2();render()}"
                   onchange="syncH2();render()"> mm
        </div>
        <div class="divider"></div>
        <span class="grid-info" id="gridInfo">--</span>
        <div class="divider"></div>
        <span class="hint">拖动滑块或直接输入数值,网格自动计算</span>
    </div>

    <!-- Row 4 -->
    <div class="row">
        <div class="queue-area">
            <label>队列(点击移除):</label>
            <div class="queue-items" id="queueItems"></div>
            <button class="btn btn-sm btn-clear" onclick="clearQueue()">清空</button>
        </div>
        <div class="divider"></div>
        <span class="hint">A4纸 · 打印时100%缩放 · 最小边距 · 取消页眉页脚</span>
    </div>
</div>

<div class="cut-hint">⬆ 沿边框裁剪 · 图标在左、名字横排 ⬆</div>
<div class="page-wrap">
    <div class="grid" id="grid"></div>
</div>

<script>
var PRESETS=['🍑','🍉','🐲','🍒','🥑','⭐','🏷️','🌸','🍀','🐻','🎀','❤️','🌻','🎵','🍓','🐼','🌈','☀️','🦋','🍭'];
var iconQueue=[];
var mode='cycle';
var PW=192, PH=285;

/* 初始化 */
(function(){
    var box=document.getElementById('presetIcons');
    PRESETS.forEach(function(e){
        var d=document.createElement('div');
        d.className='preset-btn'; d.textContent=e;
        d.onclick=function(){addToQueue(e);};
        box.appendChild(d);
    });
    ['🍑','🍉','🐲','🍒','🥑','⭐','🏷️'].forEach(function(e){iconQueue.push(e);});
    updateQ(); render();
})();

/* 模式 */
function setMode(m,btn){
    mode=m;
    document.querySelectorAll('.mode-btn').forEach(function(b){b.classList.remove('active');});
    btn.classList.add('active'); render();
}

/* 队列 */
function addToQueue(icon){iconQueue.push(icon);updateQ();render();}
function addCustomIcon(){
    var v=document.getElementById('customIconInput').value.trim();
    if(!v)return; iconQueue.push(v);
    document.getElementById('customIconInput').value='';
    updateQ();render();
}
function handleFileUpload(inp){
    var fs=inp.files; if(!fs)return;
    for(var i=0;i<fs.length;i++){
        (function(f){
            var r=new FileReader();
            r.onload=function(e){iconQueue.push({t:'img',s:e.target.result});updateQ();render();};
            r.readAsDataURL(f);
        })(fs[i]);
    }
    inp.value='';
}
function removeFromQueue(i){iconQueue.splice(i,1);updateQ();render();}
function clearQueue(){iconQueue=[];updateQ();render();}
function updateQ(){
    var c=document.getElementById('queueItems');
    if(!iconQueue.length){c.innerHTML='<span class="queue-empty">请从上方选择图标</span>';return;}
    var h='';
    iconQueue.forEach(function(it,i){
        h+='<span class="queue-tag" onclick="removeFromQueue('+i+')" title="点击移除">';
        if(typeof it==='string') h+=it;
        else if(it&&it.t==='img') h+='<img src="'+it.s+'">';
        h+='<span class="rm">✕</span></span>';
    });
    c.innerHTML=h;
}
function getIcon(idx){
    if(!iconQueue.length||mode==='none')return null;
    if(mode==='same')return iconQueue[0];
    return iconQueue[idx%iconQueue.length];
}

/* 滑块同步 */
function syncW(v){document.getElementById('widthInput').value=v;render();}
function syncH(v){document.getElementById('heightInput').value=v;render();}
function syncW2(){document.getElementById('widthSlider').value=document.getElementById('widthInput').value;}
function syncH2(){document.getElementById('heightSlider').value=document.getElementById('heightInput').value;}

/* 渲染 */
function render(){
    var name=document.getElementById('nameInput').value.trim()||'姓名';
    var ff=document.getElementById('fontSelect').value;
    var fs=parseInt(document.getElementById('fontSizeInput').value)||13;
    var is=parseInt(document.getElementById('iconSizeInput').value)||10;
    var bd=document.getElementById('borderSelect').value;

    var tw=parseFloat(document.getElementById('widthInput').value)||50;
    var th=parseFloat(document.getElementById('heightInput').value)||15;
    tw=Math.max(15,Math.min(200,tw));
    th=Math.max(6,Math.min(80,th));

    var cols=Math.max(1,Math.floor(PW/tw));
    var rows=Math.max(1,Math.floor(PH/th));
    var total=cols*rows;

    document.getElementById('gridInfo').textContent=cols+'列 × '+rows+'行 = '+total+'张/页';

    var g=document.getElementById('grid');
    g.style.gridTemplateColumns='repeat('+cols+','+tw+'mm)';
    g.style.gridTemplateRows='repeat('+rows+','+th+'mm)';
    g.innerHTML='';

    for(var i=0;i<total;i++){
        var tag=document.createElement('div');
        tag.className='tag';
        tag.style.border=bd;

        var icon=getIcon(i);
        if(icon){
            var ie=document.createElement('span');
            ie.className='icon';
            if(typeof icon==='string'){
                ie.textContent=icon;
                ie.style.fontSize=is+'pt';
            }else if(icon.t==='img'){
                var img=document.createElement('img');
                img.src=icon.s;
                var ims=Math.min(th*0.65,is*0.45);
                img.style.width=ims+'mm'; img.style.height=ims+'mm';
                ie.appendChild(img);
            }
            tag.appendChild(ie);
        }

        var ns=document.createElement('span');
        ns.className='name-text';
        ns.textContent=name;
        ns.style.fontFamily=ff;
        ns.style.fontSize=fs+'pt';
        tag.appendChild(ns);

        g.appendChild(tag);
    }
}

render();
</script>

</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名贴生成器 竖版</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Long+Cang&family=Ma+Shan+Zheng&family=ZCOOL+QingKe+HuangYou&family=ZCOOL+XiaoWei&family=Zhi+Mang+Xing&family=Noto+Sans+SC:wght@300;400;500;700&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
    <style>
        @page { size: A4 portrait; margin: 6mm 9mm; }
        * { margin: 0; padding: 0; box-sizing: border-box; }

        body {
            font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
            background: #f5f2ec;
        }

        /* ========== 控制面板 ========== */
        .controls {
            position: sticky;
            top: 0;
            z-index: 100;
            padding: 18px 26px 14px;
            background: linear-gradient(145deg, #1a1a1a 0%, #252018 100%);
            color: #ddd8ce;
            font-size: 13.5px;
            box-shadow: 0 4px 24px rgba(0,0,0,0.3);
            border-bottom: 1px solid #3a3530;
        }

        .row {
            display: flex;
            align-items: center;
            gap: 10px;
            flex-wrap: wrap;
            margin-bottom: 10px;
        }
        .row:last-child { margin-bottom: 0; }

        .row-title {
            font-size: 17px;
            font-weight: 700;
            color: #fff;
            letter-spacing: 0.08em;
            margin-right: 4px;
        }

        .divider {
            width: 1px;
            height: 20px;
            background: #4a4540;
            flex-shrink: 0;
        }

        label {
            font-weight: 500;
            white-space: nowrap;
            font-size: 13px;
            color: #bbb5a8;
        }

        input[type="text"], select {
            padding: 5px 10px;
            font-size: 13.5px;
            border: 1px solid #555;
            border-radius: 5px;
            background: #2e2e2e;
            color: #eee;
            outline: none;
            transition: border-color 0.2s;
        }
        input[type="text"]:focus, select:focus { border-color: #c8a951; }
        select { cursor: pointer; padding-right: 6px; }

        #nameInput { width: 85px; }
        #customIconInput {
            width: 60px;
            text-align: center;
            font-size: 17px;
        }
        #fontSizeInput { width: 52px; text-align: center; }

        .btn {
            padding: 6px 14px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 12.5px;
            font-weight: 600;
            letter-spacing: 0.03em;
            transition: all 0.2s ease;
        }
        .btn-sm { padding: 4px 11px; font-size: 11.5px; }
        .btn-add { background: #4a6e3a; color: #c8e0b4; }
        .btn-add:hover { background: #5a8248; }
        .btn-clear { background: #5a3a3a; color: #e0b4b4; }
        .btn-clear:hover { background: #6e4848; }
        .btn-print { background: #c8a951; color: #1a1a1a; }
        .btn-print:hover { background: #d4b85e; transform: translateY(-1px); }
        .btn-upload {
            background: #3a5a6e;
            color: #b4d4e0;
            position: relative;
            overflow: hidden;
        }
        .btn-upload:hover { background: #4a6e82; }
        .btn-upload input[type="file"] {
            position: absolute;
            inset: 0;
            opacity: 0;
            cursor: pointer;
            font-size: 0;
        }

        /* 预设图标 */
        .preset-icons {
            display: flex;
            gap: 4px;
            flex-wrap: wrap;
        }
        .preset-btn {
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 2px solid #4a4540;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            background: #2e2a26;
            transition: all 0.15s;
            user-select: none;
        }
        .preset-btn:hover {
            border-color: #c8a951;
            background: #3a3630;
            transform: scale(1.12);
        }

        /* 图标队列 */
        .queue-area {
            display: flex;
            align-items: center;
            gap: 8px;
            flex-wrap: wrap;
        }
        .queue-items {
            display: flex;
            gap: 4px;
            align-items: center;
            flex-wrap: wrap;
            min-height: 30px;
            padding: 4px 8px;
            background: #242220;
            border-radius: 6px;
            border: 1px solid #3a3835;
            min-width: 160px;
            max-width: 52vw;
        }
        .queue-tag {
            display: inline-flex;
            align-items: center;
            gap: 2px;
            padding: 2px 5px;
            background: #333028;
            border-radius: 4px;
            font-size: 15px;
            cursor: pointer;
            transition: background 0.15s;
            max-height: 28px;
        }
        .queue-tag:hover { background: #5a3a3a; }
        .queue-tag img {
            width: 18px;
            height: 18px;
            object-fit: contain;
            border-radius: 2px;
        }
        .queue-tag .remove {
            font-size: 9px;
            color: #777;
            margin-left: 1px;
        }
        .queue-tag:hover .remove { color: #e88; }
        .queue-empty { color: #666; font-size: 11.5px; font-style: italic; }

        /* 模式 */
        .mode-group {
            display: flex;
            border-radius: 5px;
            overflow: hidden;
            border: 1px solid #555;
        }
        .mode-btn {
            padding: 4px 13px;
            font-size: 11.5px;
            font-weight: 500;
            cursor: pointer;
            background: #2e2e2e;
            color: #999;
            border: none;
            transition: all 0.2s;
        }
        .mode-btn.active { background: #c8a951; color: #1a1a1a; }
        .mode-btn:hover:not(.active) { background: #3a3a3a; }

        .hint {
            font-size: 10.5px;
            color: #666;
            line-height: 1.6;
        }

        /* ========== 标签网格 ========== */
        .page-wrap {
            padding: 3mm 0 12mm;
            display: flex;
            justify-content: center;
        }
        .grid {
            display: grid;
            grid-template-columns: repeat(16, 12mm);
            grid-template-rows: repeat(6, 45mm);
            justify-content: center;
        }

        .tag {
            border: 0.35mm dashed #ccc;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            gap: 0.5mm;
            -webkit-print-color-adjust: exact;
            print-color-adjust: exact;
        }

        .tag .icon {
            font-size: 10pt;
            line-height: 1;
        }
        .tag .icon img {
            width: 10mm;
            height: 10mm;
            object-fit: contain;
        }

        .tag .char {
            line-height: 1;
            color: #1a1a1a;
            font-weight: 400;
        }
        .tag .char + .char { margin-top: 1.5mm; }

        .cut-hint {
            text-align: center;
            color: #bbb;
            font-size: 11px;
            padding: 1mm 0 0;
        }

        @media print {
            .controls { display: none !important; }
            .cut-hint { display: none !important; }
            body { background: #fff; }
        }
    </style>
</head>
<body>

<div class="controls">
    <!-- 第一行 -->
    <div class="row">
        <span class="row-title">姓名贴</span>
        <div class="divider"></div>
        <label>姓名:</label>
        <input type="text" id="nameInput" value="搁得平" maxlength="6"
               onkeydown="if(event.key==='Enter')render()">
        <div class="divider"></div>
        <label>字体:</label>
        <select id="fontSelect" onchange="render()">
            <option value="'Microsoft YaHei','PingFang SC',sans-serif">微软雅黑</option>
            <option value="'SimHei','Microsoft YaHei',sans-serif">黑体</option>
            <option value="'SimSun','Songti SC',serif">宋体</option>
            <option value="'KaiTi','STKaiti','Kaiti SC',serif">楷体</option>
            <option value="'FangSong','STFangsong',serif">仿宋</option>
            <option value="'Noto Sans SC',sans-serif">思源黑体</option>
            <option value="'Noto Serif SC',serif">思源宋体</option>
            <option value="'ZCOOL XiaoWei',serif">站酷小薇</option>
            <option value="'Ma Shan Zheng',cursive">马善政楷</option>
            <option value="'ZCOOL QingKe HuangYou',sans-serif">站酷庆科黄油</option>
            <option value="'Long Cang',cursive">龙藏体</option>
            <option value="'Zhi Mang Xing',cursive">志莽行书</option>
        </select>
        <div class="divider"></div>
        <label>字号:</label>
        <input type="text" id="fontSizeInput" value="13" maxlength="2"
               onkeydown="if(event.key==='Enter')render()" title="名字字号(pt)"> pt
        <div class="divider"></div>
        <label>图标大小:</label>
        <input type="text" id="iconSizeInput" value="10" maxlength="2"
               onkeydown="if(event.key==='Enter')render()" title="图标大小(pt)"> pt
        <div class="divider"></div>
        <label>模式:</label>
        <div class="mode-group">
            <button class="mode-btn active" onclick="setMode('cycle',this)">循环</button>
            <button class="mode-btn" onclick="setMode('same',this)">统一</button>
            <button class="mode-btn" onclick="setMode('none',this)">无图标</button>
        </div>
        <button class="btn btn-print" onclick="window.print()">打印 Ctrl+P</button>
    </div>

    <!-- 第二行 -->
    <div class="row">
        <label>快捷:</label>
        <div class="preset-icons" id="presetIcons"></div>
        <div class="divider"></div>
        <label>自定义:</label>
        <input type="text" id="customIconInput" placeholder="输入"
               onkeydown="if(event.key==='Enter')addCustomIcon()">
        <button class="btn btn-sm btn-add" onclick="addCustomIcon()">添加</button>
        <div class="divider"></div>
        <label>上传图片:</label>
        <div class="btn btn-sm btn-upload">
            选择文件
            <input type="file" accept="image/*" multiple onchange="handleFileUpload(this)">
        </div>
        <span class="hint">支持 png / jpg / svg,会裁剪成正方形显示</span>
    </div>

    <!-- 第三行 -->
    <div class="row">
        <div class="queue-area">
            <label>图标队列(点击移除):</label>
            <div class="queue-items" id="queueItems">
                <span class="queue-empty">请从上方选择图标</span>
            </div>
            <button class="btn btn-sm btn-clear" onclick="clearQueue()">清空</button>
        </div>
        <div class="divider"></div>
        <span class="hint">
            A4纸 · 12mm×45mm标签 · 96张/页 · 打印时设100%缩放·最小边距·取消页眉页脚
        </span>
    </div>
</div>

<div class="cut-hint">⬆ 沿虚线裁剪 · 图标在名字上方 ⬆</div>
<div class="page-wrap">
    <div class="grid" id="grid"></div>
</div>

<script>
    /* ===== 预设列表 ===== */
    var PRESETS = ['🍑','🍉','🐲','🍒','🥑','⭐','🏷️','🌸','🍀','🐻','🎀','❤️','🌻','🎵','🍓','🐼','🌈','☀️','🦋','🍭'];

    /* ===== 状态 ===== */
    var iconQueue = []; // 元素可以是字符串(emoji) 或 {type:'img', src:'data:...'}
    var mode = 'cycle';

    /* ===== 初始化预设按钮 ===== */
    (function(){
        var box = document.getElementById('presetIcons');
        PRESETS.forEach(function(e){
            var d = document.createElement('div');
            d.className = 'preset-btn';
            d.textContent = e;
            d.onclick = function(){ addToQueue(e); };
            box.appendChild(d);
        });
        // 默认加载一些
        ['🍑','🍉','🐲','🍒','🥑','⭐','🏷️'].forEach(function(e){ iconQueue.push(e); });
        updateQueueDisplay();
        render();
    })();

    /* ===== 模式 ===== */
    function setMode(m, btn) {
        mode = m;
        document.querySelectorAll('.mode-btn').forEach(function(b){ b.classList.remove('active'); });
        btn.classList.add('active');
        render();
    }

    /* ===== 队列操作 ===== */
    function addToQueue(icon) {
        iconQueue.push(icon);
        updateQueueDisplay();
        render();
    }

    function addCustomIcon() {
        var input = document.getElementById('customIconInput');
        var val = input.value.trim();
        if (!val) return;
        iconQueue.push(val);
        input.value = '';
        updateQueueDisplay();
        render();
    }

    function handleFileUpload(input) {
        var files = input.files;
        if (!files || files.length === 0) return;
        for (var i = 0; i < files.length; i++) {
            (function(file){
                var reader = new FileReader();
                reader.onload = function(e) {
                    iconQueue.push({ type: 'img', src: e.target.result });
                    updateQueueDisplay();
                    render();
                };
                reader.readAsDataURL(file);
            })(files[i]);
        }
        input.value = ''; // 重置,允许重复上传同一文件
    }

    function removeFromQueue(index) {
        iconQueue.splice(index, 1);
        updateQueueDisplay();
        render();
    }

    function clearQueue() {
        iconQueue = [];
        updateQueueDisplay();
        render();
    }

    function updateQueueDisplay() {
        var container = document.getElementById('queueItems');
        if (iconQueue.length === 0) {
            container.innerHTML = '<span class="queue-empty">请从上方选择图标</span>';
            return;
        }
        var html = '';
        for (var i = 0; i < iconQueue.length; i++) {
            var item = iconQueue[i];
            if (typeof item === 'string') {
                html += '<span class="queue-tag" onclick="removeFromQueue('+i+')" title="点击移除">'
                     + item + '<span class="remove">✕</span></span>';
            } else if (item && item.type === 'img') {
                html += '<span class="queue-tag" onclick="removeFromQueue('+i+')" title="点击移除">'
                     + '<img src="'+item.src+'">'
                     + '<span class="remove">✕</span></span>';
            }
        }
        container.innerHTML = html;
    }

    /* ===== 获取图标 ===== */
    function getIcon(index) {
        if (iconQueue.length === 0 || mode === 'none') return null;
        if (mode === 'same') return iconQueue[0];
        return iconQueue[index % iconQueue.length];
    }

    /* ===== 渲染 ===== */
    function render() {
        var name = document.getElementById('nameInput').value.trim() || '姓名';
        var fontFamily = document.getElementById('fontSelect').value;
        var fontSize = parseInt(document.getElementById('fontSizeInput').value) || 13;
        var iconSize = parseInt(document.getElementById('iconSizeInput').value) || 10;

        var grid = document.getElementById('grid');
        grid.innerHTML = '';

        for (var i = 0; i < 96; i++) {
            var tag = document.createElement('div');
            tag.className = 'tag';

            var icon = getIcon(i);
            if (icon) {
                var iconEl = document.createElement('span');
                iconEl.className = 'icon';
                iconEl.style.fontSize = iconSize + 'pt';

                if (typeof icon === 'string') {
                    iconEl.textContent = icon;
                } else if (icon && icon.type === 'img') {
                    var img = document.createElement('img');
                    img.src = icon.src;
                    img.style.width = iconSize * 1.2 + 'mm';
                    img.style.height = iconSize * 1.2 + 'mm';
                    iconEl.appendChild(img);
                }
                tag.appendChild(iconEl);
            }

            var chars = name.split('');
            for (var j = 0; j < chars.length; j++) {
                var span = document.createElement('span');
                span.className = 'char';
                span.textContent = chars[j];
                span.style.fontFamily = fontFamily;
                span.style.fontSize = fontSize + 'pt';
                tag.appendChild(span);
            }

            grid.appendChild(tag);
        }
    }

    /* 首次渲染 */
    render();
</script>

</body>
</html>
推荐
netfox2008 发表于 2026-8-31 20:01

一楼最终版的姓名贴,横版没问题,竖版我这边是图像我姓名分成两排,并不是跟二楼一样竖排是姓名立着竖排。
3#
irundream 发表于 2026-8-31 18:36
4#
yourbestrun 发表于 2026-8-31 18:38
请问这个代码怎么运行呢 ?
5#
batbat001 发表于 2026-8-31 18:49
可以让豆包试试
6#
xbb 发表于 2026-8-31 18:53
yourbestrun 发表于 2026-8-31 18:38
请问这个代码怎么运行呢 ?

代码保存到文本文件中,打开后另存为html文件就行了。
7#
afti 发表于 2026-8-31 19:14
开学季正好使用
8#
yangyanghq 发表于 2026-8-31 19:17
开学了,就用上了呗哈……
9#
WAN1314 发表于 2026-8-31 19:24
搞个手机版的,方便点
10#
zkl201952pojie 发表于 2026-8-31 19:31
喜迎九一,多谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-8-31 23:36

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表