HTML5钢琴键盘特效

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML5钢琴键盘特效</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(to bottom, #1a1a2e, #16213e);
            font-family: 'Arial', sans-serif;
            flex-direction: column;
            padding: 20px;
        }

        h1 {
            color: #fff;
            margin-bottom: 30px;
            text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
        }

        .piano-container {
            display: flex;
            position: relative;
            margin-bottom: 50px;
        }

        .key {
            cursor: pointer;
            position: relative;
            display: flex;
            justify-content: center;
            align-items: flex-end;
            padding-bottom: 20px;
            font-weight: bold;
            user-select: none;
        }

        .white-key {
            width: 60px;
            height: 200px;
            background: linear-gradient(to bottom, #fff 0%, #f5f5f5 100%);
            border: 1px solid #ccc;
            border-radius: 0 0 5px 5px;
            box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
            color: #333;
            z-index: 1;
            transition: all 0.1s;
        }

        .white-key.active {
            background: linear-gradient(to bottom, #e0e0e0 0%, #d5d5d5 100%);
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
            transform: translateY(3px);
        }

        .black-key {
            width: 36px;
            height: 120px;
            background: linear-gradient(to bottom, #333 0%, #000 100%);
            border-radius: 0 0 5px 5px;
            margin-left: -18px;
            margin-right: -18px;
            z-index: 2;
            color: #fff;
            transition: all 0.1s;
        }

        .black-key.active {
            background: linear-gradient(to bottom, #222 0%, #111 100%);
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
            transform: translateY(2px);
        }

        .key-label {
            pointer-events: none;
        }

        .link {
            margin-top: 30px;
        }

        .link a {
            color: #fff;
            background: rgba(255, 255, 255, 0.2);
            padding: 10px 20px;
            border-radius: 30px;
            text-decoration: none;
            font-weight: bold;
            transition: all 0.3s;
        }

        .link a:hover {
            background: rgba(255, 255, 255, 0.3);
            box-shadow: 0 0 15px rgba(255, 255, 255, 0.2);
        }

        .instructions {
            color: #fff;
            margin-top: 20px;
            text-align: center;
            opacity: 0.7;
        }
    </style>
</head>
<body>
    <h1>HTML5钢琴键盘特效</h1>
    
    <div class="piano-container">
        <!-- 白键 -->
        <div class="key white-key" data-note="C">
            <span class="key-label">C</span>
        </div>
        <div class="key white-key" data-note="D">
            <span class="key-label">D</span>
        </div>
        <div class="key white-key" data-note="E">
            <span class="key-label">E</span>
        </div>
        <div class="key white-key" data-note="F">
            <span class="key-label">F</span>
        </div>
        <div class="key white-key" data-note="G">
            <span class="key-label">G</span>
        </div>
        <div class="key white-key" data-note="A">
            <span class="key-label">A</span>
        </div>
        <div class="key white-key" data-note="B">
            <span class="key-label">B</span>
        </div>
        
        <!-- 黑键 -->
        <div class="key black-key" data-note="C#">
            <span class="key-label">C#</span>
        </div>
        <div class="key black-key" data-note="D#">
            <span class="key-label">D#</span>
        </div>
        <div class="key black-key" data-note="F#">
            <span class="key-label">F#</span>
        </div>
        <div class="key black-key" data-note="G#">
            <span class="key-label">G#</span>
        </div>
        <div class="key black-key" data-note="A#">
            <span class="key-label">A#</span>
        </div>
    </div>
    
    <p class="instructions">点击键盘或按键盘上的A,S,D,F,G,H,J键演奏</p>
    
    <div class="link">
        <a href="http://2sf.100wanfu.com" target="_blank">访问示例网站</a>
    </div>

    <script>
        // 键盘按键映射
        const keyMap = {
            'a': 'C',
            'w': 'C#',
            's': 'D',
            'e': 'D#',
            'd': 'E',
            'f': 'F',
            't': 'F#',
            'g': 'G',
            'y': 'G#',
            'h': 'A',
            'u': 'A#',
            'j': 'B'
        };

        // 音频上下文
        const audioContext = new (window.AudioContext || window.webkitAudioContext)();
        
        // 获取所有琴键
        const keys = document.querySelectorAll('.key');
        
        // 鼠标点击事件
        keys.forEach(key => {
            key.addEventListener('mousedown', () => playNote(key));
            key.addEventListener('mouseup', () => stopNote(key));
            key.addEventListener('mouseleave', () => stopNote(key));
        });
        
        // 键盘事件
        document.addEventListener('keydown', (e) => {
            const note = keyMap[e.key.toLowerCase()];
            if (note) {
                const key = document.querySelector(`.key[data-note="${note}"]`);
                if (key) {
                    key.classList.add('active');
                    playNote(key);
                }
            }
        });
        
        document.addEventListener('keyup', (e) => {
            const note = keyMap[e.key.toLowerCase()];
            if (note) {
                const key = document.querySelector(`.key[data-note="${note}"]`);
                if (key) {
                    key.classList.remove('active');
                    stopNote(key);
                }
            }
        });
        
        // 播放音符
        function playNote(key) {
            if (!key.classList.contains('active')) {
                key.classList.add('active');
                
                const note = key.getAttribute('data-note');
                const frequency = getFrequency(note);
                
                const oscillator = audioContext.createOscillator();
                const gainNode = audioContext.createGain();
                
                oscillator.type = 'sine';
                oscillator.frequency.value = frequency;
                
                gainNode.gain.value = 0.3;
                
                oscillator.connect(gainNode);
                gainNode.connect(audioContext.destination);
                
                oscillator.start();
                
                key.oscillator = oscillator;
                key.gainNode = gainNode;
            }
        }
        
        // 停止音符
        function stopNote(key) {
            if (key.classList.contains('active')) {
                key.classList.remove('active');
                
                if (key.gainNode) {
                    key.gainNode.gain.exponentialRampToValueAtTime(
                        0.001, 
                        audioContext.currentTime + 0.1
                    );
                    
                    if (key.oscillator) {
                        setTimeout(() => {
                            key.oscillator.stop();
                            key.oscillator.disconnect();
                            key.gainNode.disconnect();
                        }, 100);
                    }
                }
            }
        }
        
        // 获取音符频率
        function getFrequency(note) {
            const notes = {
                'C': 261.63,
                'C#': 277.18,
                'D': 293.66,
                'D#': 311.13,
                'E': 329.63,
                'F': 349.23,
                'F#': 369.99,
                'G': 392.00,
                'G#': 415.30,
                'A': 440.00,
                'A#': 466.16,
                'B': 493.88
            };
            
            return notes[note] || 440;
        }
    </script>
</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值