【源代码】程序员电脑前打字效果,纯html+css实现

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>程序员动画</title>
    <style>
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
        }
        body {
          display: flex;
          justify-content: center;
          align-items: center;
          min-height: 100vh;
          background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
          font-family: 'Courier New', monospace;
          overflow: hidden;
        }
        .scene {
          position: relative;
          width: 650px;
          height: 480px;
          zoom: 0.85;
        }
        
        /* 桌子 */
        .desk {
          position: absolute;
          bottom: 120px;
          left: 50px;
          width: 400px;
          height: 18px;
          background: linear-gradient(180deg, #a0694b 0%, #8B4513 50%, #654321 100%);
          border-radius: 3px;
          box-shadow: 0 5px 15px rgba(0,0,0,0.3);
          z-index: 50;
        }
        .desk-leg-left, .desk-leg-right {
          position: absolute;
          bottom: -80px;
          width: 12px;
          height: 80px;
          background: linear-gradient(90deg, #654321, #8B4513, #654321);
        }
        .desk-leg-left { left: 25px; }
        .desk-leg-right { right: 25px; }
        
        /* 显示器 */
        .monitor {
          position: absolute;
          bottom: 158px;
          left: 120px;
          width: 200px;
          height: 140px;
          background: #2d2d2d;
          border: 4px solid #1a1a1a;
          border-radius: 10px;
          box-shadow: 0 5px 20px rgba(0,0,0,0.5);
          z-index: 51;
        }
        .screen {
          position: absolute;
          top: 8px;
          left: 8px;
          width: 180px;
          height: 110px;
          background: #1e1e1e;
          border-radius: 3px;
          overflow: hidden;
          padding: 8px;
        }
        .code-line {
          font-size: 8px;
          color: #9cdcfe;
          height: 12px;
          white-space: nowrap;
          overflow: hidden;
        }
        .code-line.keyword { color: #c586c0; }
        .code-line.string { color: #ce9178; }
        .code-line.function { color: #dcdcaa; }
        .code-line.comment { color: #6a9955; }
        .code-line.error { color: #f44747; background: rgba(244,71,71,0.1); }
        
        .monitor-stand {
          position: absolute;
          bottom: -20px;
          left: 50%;
          transform: translateX(-50%);
          width: 25px;
          height: 20px;
          background: #1a1a1a;
        }
        .monitor-base {
          position: absolute;
          bottom: -25px;
          left: 50%;
          transform: translateX(-50%);
          width: 55px;
          height: 6px;
          background: #1a1a1a;
          border-radius: 3px;
        }
        
        /* 键盘 */
        .keyboard {
          position: absolute;
          bottom: 140px;
          left: 330px;
          width: 110px;
          height: 35px;
          background: #333;
          border-radius: 4px;
          padding: 4px;
          display: flex;
          flex-wrap: wrap;
          gap: 2px;
          justify-content: center;
          align-content: center;
          box-shadow: 0 2px 8px rgba(0,0,0,0.3);
          z-index: 52;
        }
        .key {
          width: 8px;
          height: 8px;
          background: #555;
          border-radius: 1px;
          transition: transform 0.1s, background 0.1s;
        }
        .key.pressed {
          transform: translateY(1px);
          background: #777;
        }
        
        /* 椅子 */
        .chair {
          position: absolute;
          bottom: 175px;
          left: 430px;
          z-index: 30;
        }
        .chair-seat {
          position: relative;
          width: 75px;
          height: 15px;
          background: #2d2d2d;
          border-radius: 4px;
          top: 80px;
        }
        .chair-back {
          position: absolute;
          top: 10px;
          right: -8px;
          width: 15px;
          height: 75px;
          background: linear-gradient(90deg, #3d3d3d, #2d2d2d);
          border-radius: 6px;
        }
        .chair-leg {
          position: absolute;
          top: 95px;
          left: 35px;
          width: 6px;
          height: 45px;
          background: #1a1a1a;
        }
        .chair-base {
          position: absolute;
          top: 138px;
          left: 10px;
          width: 55px;
          height: 6px;
          background: #1a1a1a;
          border-radius: 3px;
        }
        .chair-wheel1, .chair-wheel2 {
          position: absolute;
          top: 142px;
          width: 8px;
          height: 8px;
          background: #111;
          border-radius: 50%;
        }
        .chair-wheel1 { left: 8px; }
        .chair-wheel2 { left: 58px; }
        
        /* 程序员 - 上半身 */
        .programmer-upper {
          position: absolute;
          bottom: 132px;
          left: 435px;
          z-index: 65;
        }
        
        .body-container {
          animation: bodyMove 3s ease-in-out infinite;
        }
        @keyframes bodyMove {
          0%, 100% { transform: translateY(0); }
          50% { transform: translateY(-2px); }
        }
        
        /* 头部 */
        .head {
          position: relative;
          width: 50px;
          height: 60px;
          background: #f2bbad;
          border-radius: 25px 25px 20px 20px;
          border: 3px solid #333;
          margin-left: 5px;
          animation: headMove 4s ease-in-out infinite;
        }
        @keyframes headMove {
          0%, 100% { transform: rotate(3deg); }
          50% { transform: rotate(6deg); }
        }
        
        /* 头发 */
        .hair {
          position: absolute;
          top: -2px;
          left: 0px;
          width: 50px;
          height: 28px;
          background: #452824;
          border-radius: 22px 22px 5px 5px;
          border: 3px solid #333;
          border-bottom: none;
        }
        .hair-side {
          position: absolute;
          top: 18px;
          right: -3px;
          width: 10px;
          height: 20px;
          background: #452824;
          border-radius: 4px;
          border: 2px solid #333;
          border-left: none;
        }
        
        /* 眼睛 */
        .eye {
          position: absolute;
          top: 24px;
          left: 12px;
          width: 5px;
          height: 5px;
          background: #333;
          border-radius: 50%;
          animation: blink 4s infinite;
        }
        @keyframes blink {
          0%, 95%, 100% { transform: scaleY(1); }
          97% { transform: scaleY(0.1); }
        }
        
        /* 眼镜 */
        .glasses {
          position: absolute;
          top: 20px;
          left: 6px;
          width: 18px;
          height: 12px;
          border: 2px solid #444;
          border-radius: 3px;
          background: rgba(200,230,255,0.15);
        }
        .glasses-arm {
          position: absolute;
          top: 3px;
          right: -18px;
          width: 20px;
          height: 2px;
          background: #444;
        }
        
        /* 鼻子 */
        .nose {
          position: absolute;
          top: 28px;
          left: -5px;
          width: 8px;
          height: 10px;
          background: #e8a090;
          border-radius: 50% 0 0 50%;
        }
        
        /* 嘴巴 */
        .mouth {
          position: absolute;
          bottom: 10px;
          left: 12px;
          width: 6px;
          height: 2px;
          background: #c97a6a;
          border-radius: 0 0 3px 3px;
        }
        
        /* 耳朵 */
        .ear {
          position: absolute;
          top: 25px;
          right: -4px;
          width: 10px;
          height: 14px;
          background: #f2bbad;
          border-radius: 50%;
          border: 2px solid #333;
          z-index: -1;
        }
        
        /* 脖子 */
        .neck {
          width: 18px;
          height: 10px;
          background: #f2bbad;
          margin-left: 18px;
        }
        
        /* 身体 */
        .body {
          position: relative;
          bottom:-2px;
          width: 60px;
          height: 65px;
          background: #4a90d9;
          border-radius: 12px 12px 8px 8px;
          border: 3px solid #333;
        }
        
        /* 手臂 - 从身体延伸 */
        .arm {
          position: absolute;
          top: 10px;
          left: -25px;
          z-index: 60;
        }
        
        .arm-upper {
          position: relative;
          width: 50px;
          height: 16px;
          background: #4a90d9;
          border-radius: 8px;
          border: 3px solid #333;
          transform: rotate(-40deg);
          transform-origin: right center;
        }
        
        .arm-lower {
          position: absolute;
          top: 6px;
          left: -40px;
          width: 50px;
          height: 14px;
          background: #4a90d9;
          border-radius: 8px;
          border: 3px solid #333;
          transform: rotate(55deg);
          transform-origin: right center;
          animation: armMove 0.35s ease-in-out infinite;
        }
        @keyframes armMove {
          0%, 100% { transform: rotate(55deg); }
          50% { transform: rotate(58deg); }
        }
        
        /* 手 */
        .hand {
          position: absolute;
          left: -16px;
          top: 2px;
          width: 18px;
          height: 12px;
          background: #f2bbad;
          border-radius: 8px;
          border: 2px solid #daa090;
        }
        .fingers {
          position: absolute;
          bottom: -6px;
          left: 2px;
          display: flex;
          gap: 2px;
        }
        .finger {
          width: 3px;
          height: 8px;
          background: #f2bbad;
          border-radius: 2px;
          border: 1px solid #daa090;
          animation: fingerType 0.2s ease-in-out infinite;
        }
        .finger:nth-child(1) { animation-delay: 0s; }
        .finger:nth-child(2) { animation-delay: 0.06s; }
        .finger:nth-child(3) { animation-delay: 0.12s; }
        .finger:nth-child(4) { animation-delay: 0.03s; }
        
        @keyframes fingerType {
          0%, 100% { transform: translateY(0); }
          50% { transform: translateY(3px); }
        }
        
        /* 腿 - 在桌子下面 */
        .legs {
          position: absolute;
          bottom: 130px;
          left: 430px;
          z-index: 35;
        }
        .thigh {
          position: absolute;
          width: 55px;
          height: 20px;
          background: #3a3a5c;
          border-radius: 8px;
          border: 2px solid #333;
        }
        .thigh-left { top: 0; left: 0; }
        .thigh-right { top: 0; left: 10px; }
        
        .lower-leg {
          position: absolute;
          top: 14px;
          width: 16px;
          height: 72px;
          background: #3a3a5c;
          border-radius: 5px;
          border: 2px solid #333;
        }
        .lower-leg-left { left: -5px; transform: rotate(-1deg); }
        .lower-leg-right { left: -10px; transform: rotate(5deg); }
        
        .foot {
          position: absolute;
          top: 79px;
          width: 25px;
          height: 10px;
          background: #2a2a3c;
          border-radius: 3px;
          border: 2px solid #333;
        }
        .foot-left { left: -27px; }
        .foot-right { left: -10px; }
        
        /* 咖啡杯 */
        .coffee {
          position: absolute;
          bottom: 138px;
          left: 80px;
          width: 32px;
          height: 36px;
          background: linear-gradient(180deg, #fff 0%, #e8e0d8 100%);
          border-radius: 2px 2px 6px 6px;
          border: 2px solid #333;
          z-index: 53;
        }
        .coffee-handle {
          position: absolute;
          right: -8px;
          top: 8px;
          width: 8px;
          height: 15px;
          border: 2px solid #bbb;
          border-left: none;
          border-radius: 0 6px 6px 0;
        }
        .coffee-liquid {
          position: absolute;
          top: 5px;
          left: 3px;
          width: 24px;
          height: 10px;
          background: #4a2c2a;
          border-radius: 2px;
        }
        .coffee-logo {
          position: absolute;
          top: 14px;
          left: 6px;
          width: 18px;
          height: 16px;
          border: 2px solid #ddd;
          border-radius: 2px;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 9px;
          color: #999;
        }
        
        /* 蒸汽 */
        .steam {
          position: absolute;
          top: -22px;
          left: 50%;
          transform: translateX(-50%);
        }
        .steam-line {
          position: absolute;
          width: 2px;
          height: 15px;
          background: rgba(255,255,255,0.4);
          border-radius: 2px;
          animation: steam 2s ease-in-out infinite;
        }
        .steam-line:nth-child(1) { left: -6px; animation-delay: 0s; }
        .steam-line:nth-child(2) { left: 0px; animation-delay: 0.35s; }
        .steam-line:nth-child(3) { left: 6px; animation-delay: 0.7s; }
        
        @keyframes steam {
          0% { opacity: 0; transform: translateY(0) scaleX(1); }
          30% { opacity: 0.6; }
          100% { opacity: 0; transform: translateY(-18px) scaleX(0.3); }
        }
        
        .cursor {
          display: inline-block;
          width: 4px;
          height: 8px;
          background: #fff;
          animation: cursorBlink 0.8s step-end infinite;
        }
        @keyframes cursorBlink {
          0%, 50% { opacity: 1; }
          51%, 100% { opacity: 0; }
        }
    </style>
</head>

<body>
    <div class="scene">
        <!-- 椅子 - z-index: 30 -->
        <div class="chair">
            <div class="chair-back"></div>
            <div class="chair-seat"></div>
            <div class="chair-leg"></div>
            <div class="chair-base"></div>
            <div class="chair-wheel1"></div>
            <div class="chair-wheel2"></div>
        </div>

        <!-- 腿部 - z-index: 35,在桌子下面 -->
        <div class="legs">
            <div class="thigh thigh-left"></div>
            <div class="thigh thigh-right"></div>
            <div class="lower-leg lower-leg-left"></div>
            <div class="lower-leg lower-leg-right"></div>
            <div class="foot foot-left"></div>
            <div class="foot foot-right"></div>
        </div>

        <!-- 桌子 - z-index: 50 -->
        <div class="desk">
            <div class="desk-leg-left"></div>
            <div class="desk-leg-right"></div>
        </div>

        <!-- 显示器 - z-index: 51 -->
        <div class="monitor">
            <div class="screen" id="screen"></div>
            <div class="monitor-stand"></div>
            <div class="monitor-base"></div>
        </div>

        <!-- 键盘 - z-index: 52 -->
        <div class="keyboard" id="keyboard"></div>

        <!-- 咖啡杯 - z-index: 53 -->
        <div class="coffee">
            <div class="coffee-handle"></div>
            <div class="coffee-liquid"></div>
            <div class="coffee-logo">☕</div>
            <div class="steam">
                <div class="steam-line"></div>
                <div class="steam-line"></div>
                <div class="steam-line"></div>
            </div>
        </div>

        <!-- 程序员上半身 - z-index: 55 -->
        <div class="programmer-upper">
            <div class="body-container">
                <div class="head">
                    <div class="hair">
                        <div class="hair-side"></div>
                    </div>
                    <div class="ear"></div>
                    <div class="eye"></div>
                    <div class="glasses">
                        <div class="glasses-arm"></div>
                    </div>
                    <div class="nose"></div>
                    <div class="mouth"></div>
                </div>
                <div class="neck"></div>
                <div class="body">
                    <!-- 手臂从身体延伸出去 -->
                    <div class="arm">
                        <div class="arm-upper">
                            <div class="arm-lower">
                                <div class="hand">
                                    <div class="fingers">
                                        <div class="finger"></div>
                                        <div class="finger"></div>
                                        <div class="finger"></div>
                                        <div class="finger"></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        const codeLines = [
          { text: '// 程序员的日常', class: 'comment' },
          { text: 'function work() {', class: 'function' },
          { text: '  const coffee = getCoffee();', class: '' },
          { text: '  while(awake) {', class: 'keyword' },
          { text: '    writeCode();', class: '' },
          { text: '    if(hasBug()) {', class: 'keyword' },
          { text: '      debug();', class: '' },
          { text: '    }', class: '' },
          { text: '  }', class: '' },
          { text: '}', class: '' },
          { text: '', class: '' },
          { text: 'class Developer {', class: 'keyword' },
          { text: '  constructor() {', class: 'function' },
          { text: '    this.energy = 100;', class: '' },
          { text: '  }', class: '' },
          { text: '  code() {', class: 'function' },
          { text: '    return magic;', class: 'string' },
          { text: '  }', class: '' },
          { text: '}', class: '' },
          { text: '', class: '' },
          { text: 'console.log("Done!");', class: 'string' },
        ];
        
        const bugLines = [
          { text: 'Error: undefined is not fn', class: 'error' },
          { text: 'SyntaxError: unexpected ;', class: 'error' },
          { text: 'TypeError: null ref', class: 'error' },
        ];
        
        const screen = document.getElementById('screen');
        const keyboard = document.getElementById('keyboard');
        
        for (let i = 0; i < 36; i++) {
          const key = document.createElement('div');
          key.className = 'key';
          keyboard.appendChild(key);
        }
        
        const keys = document.querySelectorAll('.key');
        let currentLineIndex = 0;
        let currentCharIndex = 0;
        let currentLine = null;
        let isBugMode = false;
        
        function pressRandomKeys() {
          const count = Math.floor(Math.random() * 2) + 1;
          for (let i = 0; i < count; i++) {
            const idx = Math.floor(Math.random() * keys.length);
            keys[idx].classList.add('pressed');
            setTimeout(() => keys[idx].classList.remove('pressed'), 80);
          }
        }
        
        function typeCode() {
          if (!isBugMode && Math.random() < 0.012 && screen.children.length > 3) {
            isBugMode = true;
            const bug = bugLines[Math.floor(Math.random() * bugLines.length)];
            const bugLine = document.createElement('div');
            bugLine.className = 'code-line ' + bug.class;
            bugLine.textContent = bug.text;
            screen.appendChild(bugLine);
            setTimeout(() => {
              if (bugLine.parentNode) bugLine.remove();
              isBugMode = false;
            }, 1800);
            return;
          }
          if (isBugMode) return;
        
          const lineData = codeLines[currentLineIndex % codeLines.length];
          if (currentCharIndex === 0) {
            currentLine = document.createElement('div');
            currentLine.className = 'code-line ' + lineData.class;
            screen.appendChild(currentLine);
            while (screen.children.length > 9) screen.removeChild(screen.firstChild);
          }
          if (currentCharIndex < lineData.text.length) {
            currentLine.textContent = lineData.text.substring(0, currentCharIndex + 1);
            currentCharIndex++;
            pressRandomKeys();
          } else {
            const cursor = document.createElement('span');
            cursor.className = 'cursor';
            currentLine.appendChild(cursor);
            setTimeout(() => { if (cursor.parentNode) cursor.remove(); }, 400);
            currentCharIndex = 0;
            currentLineIndex++;
          }
        }
        
        setInterval(typeCode, 75);
    </script>
</body>

</html>

💬 评论

0/200