bloodfog 发表于 2024-6-30 13:57

闲来无聊写个简单的html5用餐座次图生成器

本帖最后由 bloodfog 于 2024-6-30 15:18 编辑

闲来无聊写个简单的html5用餐座次图生成器
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.7, maximum-scale=0.7, user-scalable=yes"/>
    <title>用餐座次图</title>
    <style>
      body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
      }
      #input-form {
            margin-bottom: 20px;
            text-align: center;
      }
      #form-elements {
            display: flex;
            align-items: center;
            gap: 10px;
      }
      #form-elements input,
      #form-elements button {
            padding: 4px;
            font-weight: bold;
            border: 1px solid #88c416;
            color: #88c416;
      }
      #form-elements input {
            height: 20px;
            color: #88c416;
      }
      #form-elements button {
            cursor: pointer;
            height: 30px;
      }
      #seating {
            position: relative;
            width: 500px;
            height: 500px;
            border-radius: 50%;
            background-color: #3399FF;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            text-align: center;
            font-weight: bold;
      }
      .seat {
            position: absolute;
            width: 60px;
            height: 30px;
            background: white;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 1px solid #88c416;
            border-radius: 10px;
            cursor: pointer;
      }
      .seat input {
            border: none;
            background: transparent;
            width: 100%;
            text-align: center;
      }
      #share-button {
            border: none;
            font-weight: bold;
            cursor: pointer;
            border-radius: 5px;
      }
      #share-button:active {
            background-color: #66a312;
      }
      @media print {
            #share-button, #input-form, button, label {
                display: none;
            }
            body {-webkit-print-color-adjust: exact;}
      }
    </style>
</head>
<body>
    <form id="input-form">
      <label for="table-info" style="color:#66CC00; height:25px; line-height:25px; font-weight:bold; padding:10px;">可拖动人员互换位置,手机端手指在姓名上停留一会在拖动</label><br><br>
      <div id="form-elements">
            <input type="text" id="table-info" required placeholder="桌号信息">
            <input type="text" id="names" required placeholder="张三、李四、王二">
            <button type="submit">生成座次</button> <button id="share-button">分享链接</button>
      </div>
    </form>
    <div id="seating">
      <div id="table-info-display"></div>
    </div><label style="color:#CCCCCC; height:25px; line-height:25px; padding:10px; font-size:10px;">© RainMan</label>
    <script>
      document.getElementById('input-form').addEventListener('submit', function(event) {
            event.preventDefault();
            const tableInfo = document.getElementById('table-info').value;
            const names = document.getElementById('names').value.split(/[,,、]/).map(name => name.trim());
            document.getElementById('table-info-display').textContent = `${tableInfo} (${names.length}人)`;
            generateSeating(names);
            updateShareLink(tableInfo, names);
      });

      function generateSeating(names) {
            const seating = document.getElementById('seating');
            const existingSeats = seating.querySelectorAll('.seat');
            existingSeats.forEach(seat => seat.remove());

            const numPeople = names.length;
            const angleStep = (2 * Math.PI) / numPeople;
            for (let i = 0; i < numPeople; i++) {
                const angle = i * angleStep - (Math.PI / 2);
                const x = 250 + 200 * Math.cos(angle);
                const y = 250 + 200 * Math.sin(angle);
                const seat = document.createElement('div');
                seat.classList.add('seat');
                seat.style.left = `${x - 30}px`;
                seat.style.top = `${y - 15}px`;
                seat.setAttribute('draggable', 'true');
                seat.addEventListener('dragstart', dragStart);
                seat.addEventListener('dragover', dragOver);
                seat.addEventListener('drop', drop);
                seat.addEventListener('dragend', dragEnd);

                // 添加触摸事件
                seat.addEventListener('touchstart', touchStart);
                seat.addEventListener('touchmove', touchMove);
                seat.addEventListener('touchend', touchEnd);

                const input = document.createElement('input');
                input.type = 'text';
                input.value = names;
                input.addEventListener('input', updateNamesList);
                seat.appendChild(input);

                seating.appendChild(seat);
            }
      }

      function updateNamesList() {
            const seats = document.querySelectorAll('.seat input');
            const names = Array.from(seats).map(input => input.value.trim());
            document.getElementById('names').value = names.join('、');
            const tableInfo = document.getElementById('table-info').value;
            document.getElementById('table-info-display').textContent = `${tableInfo} (${names.filter(name => name !== '').length}人)`;
            updateShareLink(tableInfo, names);
      }

      function updateShareLink(tableInfo, names) {
            const baseUrl = window.location.origin + window.location.pathname;
            const urlParams = new URLSearchParams();
            urlParams.set('tableInfo', tableInfo);
            urlParams.set('names', names.join('、'));
            const shareLink = `${baseUrl}?${urlParams.toString()}`;
            const shareButton = document.getElementById('share-button');
            shareButton.onclick = () => {
                if (!tableInfo.trim() || names.filter(name => name.trim() !== '').length === 0) {
                  alert('请先填写桌号和姓名信息');
                  return;
                }
                navigator.clipboard.writeText(shareLink).then(() => {
                  alert('分享链接已复制到剪切板');
                }).catch(err => {
                  alert('复制失败,请手动复制链接');
                  console.error('Could not copy text: ', err);
                });
            };
      }

      function loadFromURL() {
            const urlParams = new URLSearchParams(window.location.search);
            const tableInfo = urlParams.get('tableInfo');
            const names = urlParams.get('names');
            if (tableInfo && names) {
                document.getElementById('table-info').value = tableInfo;
                document.getElementById('names').value = names;
                document.getElementById('table-info-display').textContent = `${tableInfo} (${names.split('、').filter(name => name !== '').length}人)`;
                generateSeating(names.split('、'));
            }
      }

      let draggedInput;
      let touchStartX, touchStartY;

      function dragStart(event) {
            draggedInput = event.target.querySelector('input');
            event.dataTransfer.effectAllowed = 'move';
      }

      function dragOver(event) {
            event.preventDefault();
      }

      function drop(event) {
            event.preventDefault();
            const targetInput = event.target.closest('.seat').querySelector('input');
            if (targetInput && targetInput !== draggedInput) {
                const tempValue = draggedInput.value;
                draggedInput.value = targetInput.value;
                targetInput.value = tempValue;
                updateNamesList();
            }
      }

      function dragEnd() {
            draggedInput = null;
      }

      function touchStart(event) {
            const touch = event.touches;
            touchStartX = touch.clientX;
            touchStartY = touch.clientY;
            draggedInput = event.target.querySelector('input');
      }

      function touchMove(event) {
            event.preventDefault();
            const touch = event.touches;
            const target = document.elementFromPoint(touch.clientX, touch.clientY);
            if (target && target.closest('.seat') && target.closest('.seat') !== draggedInput.closest('.seat')) {
                const targetInput = target.closest('.seat').querySelector('input');
                if (targetInput && targetInput !== draggedInput) {
                  const tempValue = draggedInput.value;
                  draggedInput.value = targetInput.value;
                  targetInput.value = tempValue;
                  updateNamesList();
                }
            }
      }

      function touchEnd() {
            draggedInput = null;
      }

      loadFromURL();
    </script>
</body>
</html>

xu2006 发表于 2024-6-30 15:29

点赞收藏,后学习{:1_893:}

lcdeyhy 发表于 2024-6-30 15:37

非常感谢

Pwaerm 发表于 2024-6-30 16:14

优质,感谢分享

O2H2O 发表于 2024-6-30 16:26

小白提问:要怎么使用呀?

Yifan2007 发表于 2024-6-30 17:09

O2H2O 发表于 2024-6-30 16:26
小白提问:要怎么使用呀?

在vscode里面新建python项目,运行就行了

bloodfog 发表于 2024-6-30 17:28

O2H2O 发表于 2024-6-30 16:26
小白提问:要怎么使用呀?

复制代码到txt文本,修改后缀.htm 浏览器中运行

kangta520 发表于 2024-6-30 19:33

不错,看起来使用

shubiao05 发表于 2024-6-30 20:17

不错,不错,相当不错!
感谢分享!

liuam428 发表于 2024-7-1 10:36

不错,谢谢分享。。
页: [1] 2
查看完整版本: 闲来无聊写个简单的html5用餐座次图生成器