Pianino online
Graj na pianinie przez komputer lub tablet: klawiatura komputera jako klawisze, podgląd nut, nagrywanie. Nauka podstaw fortepianu online. Bezpłatnie.
-
1Wprowadź dane
Wpisz treść, wklej tekst lub załaduj plik z dysku. -
2Kliknij przycisk
Narzędzie natychmiast przetworzy Twoje dane w przeglądarce. -
3Pobierz wynik
Skopiuj gotowy tekst lub zapisz plik na urządzeniu.
return "Wynik gotowy w 0.1s";
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pro Online Piano Synth</title>
<style>
:root { --radius: 16px; --bg: #0b1220; --card-bg: rgba(255,255,255,0.04); --border: rgba(255,255,255,0.1); --text: #eef2ff; --muted: rgba(238,242,255,0.6); --accent: #6366f1; }
* { box-sizing: border-box; }
body { margin: 0; padding: 20px; font-family: system-ui, -apple-system, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.wrap { width: 100%; max-width: 900px; background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 24px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
h1 { margin: 0 0 10px 0; font-size: 24px; font-weight: 700; display: flex; align-items: center; gap: 10px; }
.status { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: #ef4444; box-shadow: 0 0 8px #ef4444; }
.status.active { background: #22c55e; box-shadow: 0 0 8px #22c55e; }
p { margin: 0 0 20px 0; color: var(--muted); line-height: 1.5; font-size: 14px; }
.kbd { background: rgba(0,0,0,0.5); border: 1px solid var(--border); padding: 3px 6px; border-radius: 6px; font-family: monospace; font-size: 12px; color: #a5b4fc; }
.piano-wrap { background: rgba(0,0,0,0.2); border: 1px solid var(--border); border-radius: 12px; padding: 16px; margin-bottom: 16px; overflow-x: auto; }
canvas { width: 100%; height: 100px; background: #000; border-radius: 8px; margin-bottom: 16px; border: 1px solid var(--border); display: block; }
svg { min-width: 600px; width: 100%; height: auto; display: block; }
.key { cursor: pointer; user-select: none; -webkit-user-select: none; touch-action: none; }
.white { fill: #f8fafc; stroke: #cbd5e1; stroke-width: 1; transition: fill 0.1s; }
.black { fill: #111827; stroke: #000; stroke-width: 1; transition: fill 0.1s; }
.active.white { fill: #c7d2fe; }
.active.black { fill: #6366f1; }
.label { font-size: 11px; fill: rgba(0,0,0,0.5); pointer-events: none; }
.label.black { fill: rgba(255,255,255,0.7); }
.btn { appearance: none; background: var(--accent); color: #fff; border: none; padding: 10px 20px; border-radius: 8px; font-weight: 600; cursor: pointer; transition: 0.2s; font-size: 14px; }
.btn:hover { background: #4f46e5; }
.btn:active { transform: scale(0.98); }
.toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; flex-wrap: wrap; gap: 10px; }
</style>
</head>
<body>
<div class="wrap">
<h1><span id="status-dot" class="status"></span> Pro Online Piano Synth</h1>
<p>Use your mouse/touch or keyboard (<span class="kbd">A</span> <span class="kbd">W</span> <span class="kbd">S</span> <span class="kbd">E</span> <span class="kbd">D</span> <span class="kbd">F</span> <span class="kbd">T</span> <span class="kbd">G</span> <span class="kbd">Y</span> <span class="kbd">H</span> <span class="kbd">U</span> <span class="kbd">J</span>) to play.</p>
<div class="toolbar">
<button class="btn" id="enable-audio" type="button">Initialize Audio Engine</button>
<span style="color:var(--muted); font-size:12px;" id="poly-count">Voices: 0 / 8</span>
</div>
<canvas id="oscilloscope" width="840" height="100" aria-label="Audio Visualizer"></canvas>
<div class="piano-wrap">
<svg id="keyboard" viewBox="0 0 840 180" aria-label="Piano keyboard" role="img"></svg>
</div>
</div>
<script>
(function () {
'use strict';
const CONFIG = {"octaves":2,"base_octave":3,"waveform":"triangle","attack":0.0200000000000000004163336342344337026588618755340576171875,"decay":0.1499999999999999944488848768742172978818416595458984375,"sustain":0.5500000000000000444089209850062616169452667236328125,"release":0.34999999999999997779553950749686919152736663818359375,"volume":0.75,"polyphony":8,"show_labels":1,"filter_cutoff":20000,"filter_reso":0,"detune":0,"visualizer":1};
const NOTE_NAMES = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];
const WHITE_ORDER = ["C","D","E","F","G","A","B"];
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" };
let ctx, master, analyser, filterNode;
const voices = new Map();
let voiceOrder = [];
const svg = document.getElementById("keyboard");
const btnEnable = document.getElementById("enable-audio");
const statusDot = document.getElementById("status-dot");
const polyCount = document.getElementById("poly-count");
const canvas = document.getElementById("oscilloscope");
const canvasCtx = canvas ? canvas.getContext("2d") : null;
function clamp(v, a, b) { return Math.max(a, Math.min(b, Number(v))); }
function noteToMidi(note, octave) { return 12 * (octave + 1) + NOTE_NAMES.indexOf(note); }
function midiToFreq(midi) { return 440 * Math.pow(2, (midi - 69) / 12); }
function makeId(note, octave) { return note + String(octave); }
async function initAudio() {
if (ctx) return;
ctx = new (window.AudioContext || window.webkitAudioContext)();
master = ctx.createGain();
master.gain.value = clamp(CONFIG.volume, 0.05, 1);
filterNode = ctx.createBiquadFilter();
filterNode.type = "lowpass";
filterNode.frequency.value = clamp(CONFIG.filter_cutoff, 20, 20000);
filterNode.Q.value = clamp(CONFIG.filter_reso, 0, 30);
if (CONFIG.visualizer && canvasCtx) {
analyser = ctx.createAnalyser();
analyser.fftSize = 2048;
filterNode.connect(master);
master.connect(analyser);
analyser.connect(ctx.destination);
drawOscilloscope();
} else {
filterNode.connect(master);
master.connect(ctx.destination);
}
if (ctx.state === "suspended") await ctx.resume();
statusDot.classList.add("active");
btnEnable.style.display = "none";
}
function drawOscilloscope() {
if (!analyser || !canvasCtx) return;
requestAnimationFrame(drawOscilloscope);
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);
canvasCtx.fillStyle = "#000";
canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = "#6366f1";
canvasCtx.beginPath();
const sliceWidth = canvas.width * 1.0 / bufferLength;
let x = 0;
for (let i = 0; i < bufferLength; i++) {
const v = dataArray[i] / 128.0;
const y = v * canvas.height / 2;
if (i === 0) canvasCtx.moveTo(x, y);
else canvasCtx.lineTo(x, y);
x += sliceWidth;
}
canvasCtx.lineTo(canvas.width, canvas.height / 2);
canvasCtx.stroke();
}
function scheduleEnvelope(gainNode, when, isOn) {
const g = gainNode.gain;
g.cancelScheduledValues(when);
if (isOn) {
g.setValueAtTime(0.0001, when);
g.linearRampToValueAtTime(1.0, when + Math.max(0.001, CONFIG.attack));
g.linearRampToValueAtTime(Math.max(0.0001, CONFIG.sustain), when + Math.max(0.001, CONFIG.attack) + Math.max(0.001, CONFIG.decay));
} else {
const cur = Math.max(0.0001, g.value);
g.setValueAtTime(cur, when);
g.linearRampToValueAtTime(0.0001, when + Math.max(0.01, CONFIG.release));
}
}
function updatePolyCount() {
if(polyCount) polyCount.textContent = `Voices: ${voices.size} / ${CONFIG.polyphony}`;
}
function startVoice(note, octave) {
initAudio();
if (!ctx || !filterNode) return;
const id = makeId(note, octave);
if (voices.has(id)) return;
while (voices.size >= clamp(CONFIG.polyphony, 1, 16) && voiceOrder.length) {
stopVoice(voiceOrder.shift(), true);
}
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.type = CONFIG.waveform || "triangle";
osc.frequency.value = midiToFreq(noteToMidi(note, octave));
osc.detune.value = CONFIG.detune || 0;
gain.gain.value = 0.0001;
osc.connect(gain);
gain.connect(filterNode);
const t = ctx.currentTime;
scheduleEnvelope(gain, t, true);
osc.start(t);
voices.set(id, { osc, gain });
voiceOrder.push(id);
const el = svg.querySelector(`[data-id="${id.replace(/"/g, '\"')}"]`);
if (el) el.classList.add("active");
updatePolyCount();
}
function stopVoice(id, immediate) {
const v = voices.get(id);
if (!v || !ctx) return;
const t = ctx.currentTime;
scheduleEnvelope(v.gain, t, false);
const stopAt = immediate ? (t + 0.02) : (t + Math.max(0.05, CONFIG.release) + 0.02);
try { v.osc.stop(stopAt); } catch (e) {}
voices.delete(id);
voiceOrder = voiceOrder.filter(x => x !== id);
const el = svg.querySelector(`[data-id="${id.replace(/"/g, '\"')}"]`);
if (el) el.classList.remove("active");
updatePolyCount();
}
function buildKeyboard() {
const octaves = clamp(CONFIG.octaves, 1, 4);
const baseOct = clamp(CONFIG.base_octave, 1, 7);
while (svg.firstChild) svg.removeChild(svg.firstChild);
const wW = 60, wH = 170, bW = 38, bH = 110;
svg.setAttribute("viewBox", `0 0 ${octaves * 7 * wW} 180`);
let x = 0;
for (let o = 0; o < octaves; o++) {
const oct = baseOct + o;
for (const n of WHITE_ORDER) {
const id = makeId(n, oct);
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttribute("class", "key");
g.dataset.id = id; g.dataset.note = n; g.dataset.octave = oct;
const r = document.createElementNS("http://www.w3.org/2000/svg", "rect");
r.setAttribute("x", x); r.setAttribute("y", 0);
r.setAttribute("rx", 6); r.setAttribute("ry", 6);
r.setAttribute("width", wW); r.setAttribute("height", wH);
r.setAttribute("class", "white");
g.appendChild(r);
if (CONFIG.show_labels) {
const t = document.createElementNS("http://www.w3.org/2000/svg", "text");
t.setAttribute("x", x + wW/2); t.setAttribute("y", wH - 18);
t.setAttribute("text-anchor", "middle"); t.setAttribute("class", "label");
t.textContent = n + oct;
g.appendChild(t);
}
svg.appendChild(g);
x += wW;
}
}
for (let o = 0; o < octaves; o++) {
const oct = baseOct + o;
const bPos = [{n:"C#",p:0},{n:"D#",p:1},{n:"F#",p:3},{n:"G#",p:4},{n:"A#",p:5}];
for (const bp of bPos) {
const id = makeId(bp.n, oct);
const bx = (o * 7 + bp.p + 1) * wW - bW/2;
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttribute("class", "key");
g.dataset.id = id; g.dataset.note = bp.n; g.dataset.octave = oct;
const r = document.createElementNS("http://www.w3.org/2000/svg", "rect");
r.setAttribute("x", bx); r.setAttribute("y", 0);
r.setAttribute("rx", 4); r.setAttribute("ry", 4);
r.setAttribute("width", bW); r.setAttribute("height", bH);
r.setAttribute("class", "black");
g.appendChild(r);
if (CONFIG.show_labels) {
const t = document.createElementNS("http://www.w3.org/2000/svg", "text");
t.setAttribute("x", bx + bW/2); t.setAttribute("y", bH - 18);
t.setAttribute("text-anchor", "middle"); t.setAttribute("class", "label black");
t.textContent = bp.n + oct;
g.appendChild(t);
}
svg.appendChild(g);
}
}
}
const pressed = new Map();
const getKeyInfo = (t) => {
const g = t?.closest?.(".key");
return g ? { id: g.dataset.id, note: g.dataset.note, oct: Number(g.dataset.octave) } : null;
};
svg.addEventListener("pointerdown", (e) => {
const k = getKeyInfo(e.target);
if (!k) return;
svg.setPointerCapture(e.pointerId);
pressed.set(e.pointerId, k.id);
startVoice(k.note, k.oct);
e.preventDefault();
});
svg.addEventListener("pointermove", (e) => {
if (!pressed.has(e.pointerId)) return;
const prev = pressed.get(e.pointerId);
const k = getKeyInfo(e.target);
if (k && k.id !== prev) {
stopVoice(prev, false);
pressed.set(e.pointerId, k.id);
startVoice(k.note, k.oct);
}
});
const endPointer = (e) => {
const id = pressed.get(e.pointerId);
if (id) stopVoice(id, false);
pressed.delete(e.pointerId);
};
svg.addEventListener("pointerup", endPointer);
svg.addEventListener("pointercancel", endPointer);
const downKeys = new Set();
window.addEventListener("keydown", (e) => {
const k = (e.key || "").toLowerCase();
if (!keyMap[k] || downKeys.has(k)) return;
downKeys.add(k);
startVoice(keyMap[k], clamp(CONFIG.base_octave, 1, 7));
});
window.addEventListener("keyup", (e) => {
const k = (e.key || "").toLowerCase();
if (!keyMap[k]) return;
downKeys.delete(k);
stopVoice(makeId(keyMap[k], clamp(CONFIG.base_octave, 1, 7)), false);
});
if (btnEnable) btnEnable.addEventListener("click", initAudio);
buildKeyboard();
})();
</script>
</body>
</html>
Oceń to narzędzie:
Powiązane narzędzia
Inne narzędzia, które mogą Ci się przydaćPianino online – graj na fortepianie w przeglądarce
Pianino online to wirtualny instrument dostępny bez instalacji – bezpośrednio w przeglądarce. Obsługiwane przez klawiaturę komputera, mysz lub ekran dotykowy. Idealne do nauki podstaw, eksperymentowania z melodiami, ćwiczenia palców i zabawy z muzyką.
Jak używać pianina online
Klawiatura komputera: klawisze A-L, W-O odpowiadają klawiszom fortepianu (biały i czarny). Mysz/dotyk: kliknij lub dotknij wirtualny klawisz. MIDI: podłącz klawiaturę MIDI przez Web MIDI API (Chrome). Oktawy: przełącz góra/dół by zmienić rejestr. Sustain: Shift trzyma dźwięk (jak pedał). Volume: slider głośności.
Klawiszownik fortepianu
Fortepian ma 88 klawiszy: 52 białe, 36 czarnych. Środkowe C (C4): centralne C, odniesienie dla strojenia. Oktawy: C1-C8, każda wyżej o 2× wyższą częstotliwość. A4 = 440 Hz (standard strojenia). Klawisze czarne (półtony): C#/Db, D#/Eb, F#/Gb, G#/Ab, A#/Bb. Gama C-dur: wszystkie białe klawisze C D E F G A B C.
Podstawowe akordy fortepianowe
C-dur: C + E + G (1, 3, 5 stopień gamy C). G-dur: G + B + D. Am (a-moll): A + C + E. F-dur: F + A + C. Progresja 1-4-5: C-F-G (wiele piosenek pop). Progresja 1-5-6-4: C-G-Am-F = "Pachelbel Canon progression" (Let It Be, No Woman No Cry, itp.). Narzędzie podświetla klawisze akordów.
Nauka gry na pianinie
Postura: prostowane plecy, ręce na wysokości klawiatury. Palce: lekko zaokrąglone (jakbyś trzymał piłkę). Lewa ręka: akompaniament (akordy). Prawa ręka: melodia. Ćwiczenie: ćwicz każdą rękę osobno, potem razem. Metronomem: zawsze ćwicz z metronomem. Aplikacje: Simply Piano, Flowkey, Playground Sessions dla zorganizowanej nauki.
Najczęstsze pytania
Czy pianino online zastąpi prawdziwy instrument?
Nie – pianino online jest dobre do: eksperymentowania, podstaw teorii, zabawy, ćwiczenia melodii. Brakuje: "touch response" (dynamika nacisku), pedał (sustain), fizycznej nauki układu klawiatury, satysfakcji z prawdziwego instrumentu. Do poważnej nauki: kup klawiaturę MIDI (88 klawiszy, weighted keys) od 300-600 zł.
Jak szybko nauczyć się grać prostą melodię?
Wybierz prostą melodię: "Oda do radości", "Happy Birthday", gamę C-dur. Zidentyfikuj nuty: skorzystaj z tutorialu nut. Ćwicz wolno: jedna nuta na raz. Zapamiętaj sekwencję bez patrzenia na nuty. Stopniowo przyspieszaj. Użyj oznaczeń palców. Prosta melodia = 30-60 minut ćwiczeń.
Jaki jest najlepszy sposób na naukę pianina online?
Structured apps: Simply Piano (gamifikacja, świetna dla dzieci), Flowkey (tysiące piosenek), Playground Sessions (z Quincy Jonesem). YouTube: Piano Tutorial Show, Rousseau (visualizacje). Teoria: musictheory.net. Nauczyciel online: Preply, AmazingTalker. Samouczek: "Alfred's Adult All-in-One Piano Course" dla dorosłych.
Co to jest MIDI i jak działa z pianinem online?
MIDI (Musical Instrument Digital Interface): standard komunikacji instrumentów. Klawiatura MIDI wysyła sygnały (nota on/off, velocity) do komputera. Web MIDI API (Chrome): przeglądarka może odbierać MIDI. Narzędzie pianino obsługuje Web MIDI jeśli masz klawiaturę MIDI podłączoną przez USB. Programy: GarageBand (Mac), LMMS (darmowy) do nagrywania MIDI.
Jak rozpoznać nuty na pięciolinii?
Treble clef (wiolinowy, lewa ręka prawa ręka wyższe): linie EGBDF (Every Good Boy Does Fine), przestrzenie FACE. Bass clef (basowy): linie GBDFA (Good Boys Do Fine Always), przestrzenie ACEG (All Cows Eat Grass). Środkowe C: między obu pięcioliniami (mała linia pomocnicza). Nuta: głowa + ogonek + belki (dla krótkich wartości).
Powiązane narzedzia: pianino MIDI recorder, metronom online i generator akordow gitarowych.