⚠️Research Use Only. Not validated for clinical diagnostic use. 3D structures are predictions and require experimental validation.

3D DNA Structure Viewer

Input any DNA sequence — select A, B, or Z-DNA — visualize the 3D helix structure in real time.

Sequence Input

0
Bases
0%
GC
0
Turns
B-DNA Physiological
A-DNA Dehydrated
Z-DNA Left-handed
Drag to rotate · Scroll to zoom · Right-click to pan · Click atoms to measure distance
View:
Measure:

Understanding DNA Helix Structures

DNA exists in three major conformations depending on the environmental conditions. The 3D viewer above generates real coordinates using standard helix parameters from Saenger (1984), allowing you to visualize the differences between A-DNA, B-DNA, and Z-DNA directly in your browser.

🔬
B-DNA (Physiological)
The most common form found in living cells. Right-handed helix with 10.5 base pairs per turn, 3.4 Å rise per bp, and 10.0 Å radius. Features asymmetric major and minor grooves.
🧫
A-DNA (Dehydrated)
Found under dehydrated conditions. Wider (11.5 Å radius) with 11 bp per turn and 2.6 Å rise. The major groove is deep and narrow; the minor groove is wide and shallow.
⟳
Z-DNA (Left-Handed)
A left-handed helix that forms in GC-rich regions under high salt conditions. Narrower (9.0 Å) with 12 bp per turn. Associated with gene regulation and chromatin remodeling.

The double helix is held together by hydrogen bonds between complementary base pairs: A pairs with T through two hydrogen bonds, while G pairs with C through three. The aromatic bases stack vertically through pi-pi interactions, stabilizing the helix interior. The major groove (wider) is where most DNA-binding proteins read the sequence, while the minor groove (narrower) is targeted by small-molecule binders.

Sign in

Access your VigyanLLM account

// ─── STATE ──────────────────────────────────────── let viewer = null; let currentData = null; // ─── INIT ────────────────────────────────────────── function initViewer() { // DNA type selector document.querySelectorAll('.dna-type-btn').forEach(btn => { btn.addEventListener('click', function() { document.querySelectorAll('.dna-type-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); updateStats(); }); }); // Build button document.getElementById('buildBtn').addEventListener('click', buildStructure); // Input changes update stats document.getElementById('seqInput').addEventListener('input', updateStats); // Toggle changes re-render if structure exists ['showBackbone','showBases','showHbonds','showLabels','showPrimerHL'].forEach(id => { document.getElementById(id).addEventListener('change', function() { if (currentData) buildStructure(); }); }); // Style/color changes re-render document.getElementById('styleSelect').addEventListener('change', function() { if (currentData) buildStructure(); }); document.getElementById('colorSelect').addEventListener('change', function() { if (currentData) buildStructure(); }); // Mobile menu var ham = document.getElementById('hamburger'); var mm = document.getElementById('mobile-menu'); if (ham) ham.addEventListener('click', function() { this.classList.toggle('active'); mm.classList.toggle('open'); }); // Initial stats updateStats(); // Auto-build — wait for 3Dmol to load waitFor3Dmol(); } function waitFor3Dmol() { if (typeof $3Dmol !== 'undefined') { buildStructure(); } else { setTimeout(waitFor3Dmol, 100); } } document.addEventListener('DOMContentLoaded', initViewer); // ─── UPDATE STATS ────────────────────────────────── function updateStats() { var seq = document.getElementById('seqInput').value.toUpperCase().replace(/[^ATGC]/g, ''); var dnaType = getSelectedType(); var params = window.DNAViewer.DNA_TYPES[dnaType]; var gc = seq.length > 0 ? Math.round((seq.split('').filter(b => b==='G'||b==='C').length / seq.length) * 100) : 0; var turns = seq.length > 0 ? (seq.length / params.basesPerTurn).toFixed(1) : '0'; document.getElementById('statLen').textContent = seq.length; document.getElementById('statGC').textContent = gc + '%'; document.getElementById('statTurns').textContent = turns; } function getSelectedType() { var active = document.querySelector('.dna-type-btn.active'); return active ? active.getAttribute('data-type') : 'B-DNA'; } // ─── BUILD STRUCTURE ────────────────────────────── function buildStructure() { var seq = document.getElementById('seqInput').value; var dnaType = getSelectedType(); var fwd = document.getElementById('fwdPrimer').value; var rev = document.getElementById('revPrimer').value; var errEl = document.getElementById('errorMsg'); errEl.style.display = 'none'; // Validate sequence var val = window.DNAViewer.validateSequence(seq); if (!val.valid) { errEl.textContent = val.error; errEl.style.display = 'block'; return; } // Validate primers if (fwd) { var fwdVal = window.DNAViewer.validatePrimer(fwd, val.cleaned); if (!fwdVal.valid) { errEl.textContent = 'Forward primer: ' + fwdVal.error; errEl.style.display = 'block'; return; } } if (rev) { var revVal = window.DNAViewer.validatePrimer(rev, val.cleaned); if (!revVal.valid) { errEl.textContent = 'Reverse primer: ' + revVal.error; errEl.style.display = 'block'; return; } } try { currentData = window.DNAViewer.generatePDB(val.cleaned, dnaType, fwd, rev); renderViewer(); showStats(); updateStats(); } catch (e) { errEl.textContent = 'Error generating structure: ' + e.message; errEl.style.display = 'block'; console.error('DNA generation error:', e); } } // ─── RENDER VIEWER ──────────────────────────────── function renderViewer() { var container = document.getElementById('viewer-3d'); container.innerHTML = ''; try { viewer = $3Dmol.createViewer(container, { backgroundColor: '#0a0a1a', antialias: true, disableFog: true }); // Add PDB model var model = viewer.addModel(currentData.pdb, 'pdb'); // Apply style applyStyle(model); // Center and zoom — use viewportProperty for auto-fit viewer.zoomTo(); // Rotate to show helix from side view viewer.rotate(90, 'y'); viewer.zoom(1.6); viewer.render(); // Resize handler window.addEventListener('resize', function() { if (viewer) { var w = container.clientWidth; var h = container.clientHeight; viewer.resize(); viewer.render(); } }); } catch (e) { console.error('3Dmol.js init failed:', e); container.innerHTML = '
🧬

3D rendering requires WebGL

Try Chrome, Firefox, or Safari

'; } } // ─── APPLY STYLE ─────────────────────────────────── function applyStyle(model) { if (!viewer || !currentData) return; var style = document.getElementById('styleSelect').value; var colorBy = document.getElementById('colorSelect').value; var showBB = document.getElementById('showBackbone').checked; var showBP = document.getElementById('showBases').checked; var showLBL = document.getElementById('showLabels').checked; var showPH = document.getElementById('showPrimerHL').checked; // Clear everything viewer.setStyle({}, {}); viewer.removeAllLabels(); var baseColors = { A: '#3B82F6', T: '#EF4444', G: '#22C55E', C: '#EAB308' }; // Determine atom style based on mode var atomStyle; if (style === 'stick') { atomStyle = { stick: { radius: 0.25, colorscheme: 'Jmol' } }; } else if (style === 'line') { atomStyle = { line: { linewidth: 3, colorscheme: 'Jmol' } }; } else if (style === 'cartoon') { atomStyle = { cartoon: { color: 'spectrum', opacity: 0.95, tubes: true } }; } else { atomStyle = { sphere: { scale: 0.5, colorscheme: 'Jmol' }, stick: { radius: 0.18, colorscheme: 'Jmol' } }; } // Apply base style to all atoms viewer.setStyle({}, atomStyle); // Override backbone atoms (P and sugar) if backbone toggle is on if (showBB) { var bbAtoms = { atom: ['P', "C4'"] }; var bbStyle; if (style === 'stick') { bbStyle = { stick: { radius: 0.3, color: '#c8c8d4' } }; } else if (style === 'line') { bbStyle = { line: { color: '#c8c8d4', linewidth: 3.5 } }; } else if (style === 'cartoon') { bbStyle = { cartoon: { color: '#c8c8d4', opacity: 0.95, tubes: true } }; } else { bbStyle = { sphere: { scale: 0.65, color: '#c8c8d4' }, stick: { radius: 0.2, color: '#a8a8b4' } }; } viewer.setStyle(bbAtoms, bbStyle); } // Override colors based on color mode if (colorBy === 'base') { ['A','T','G','C'].forEach(function(base) { var sel = { resn: base }; var s; if (style === 'stick') s = { stick: { radius: 0.25, color: baseColors[base] } }; else if (style === 'line') s = { line: { color: baseColors[base], linewidth: 3 } }; else s = { sphere: { scale: 0.5, color: baseColors[base] }, stick: { radius: 0.18, color: baseColors[base] } }; viewer.setStyle(sel, s); }); } else if (colorBy === 'strand') { var s1, s2; if (style === 'stick') { s1 = { stick: { radius: 0.25, color: '#22D3EE' } }; s2 = { stick: { radius: 0.25, color: '#F97316' } }; } else if (style === 'line') { s1 = { line: { color: '#22D3EE', linewidth: 3 } }; s2 = { line: { color: '#F97316', linewidth: 3 } }; } else { s1 = { sphere: { scale: 0.5, color: '#22D3EE' }, stick: { radius: 0.18, color: '#22D3EE' } }; s2 = { sphere: { scale: 0.5, color: '#F97316' }, stick: { radius: 0.18, color: '#F97316' } }; } viewer.setStyle({ chain: 'A' }, s1); viewer.setStyle({ chain: 'B' }, s2); } else if (colorBy === 'region') { // Default uniform color var us; if (style === 'stick') us = { stick: { radius: 0.25, color: '#94A3B8' } }; else if (style === 'line') us = { line: { color: '#94A3B8', linewidth: 3 } }; else us = { sphere: { scale: 0.5, color: '#94A3B8' }, stick: { radius: 0.18, color: '#94A3B8' } }; viewer.setStyle({}, us); // Primer highlights (most specific — apply last) if (showPH && currentData.fwdRange) { var ps; if (style === 'stick') ps = { stick: { radius: 0.35, color: '#F59E0B' } }; else ps = { sphere: { scale: 0.7, color: '#F59E0B' }, stick: { radius: 0.25, color: '#F59E0B' } }; for (var i = currentData.fwdRange[0]; i <= currentData.fwdRange[1]; i++) { viewer.setStyle({ chain: 'A', resi: i + 1 }, ps); } } if (showPH && currentData.revRange) { var rs; if (style === 'stick') rs = { stick: { radius: 0.35, color: '#EF4444' } }; else rs = { sphere: { scale: 0.7, color: '#EF4444' }, stick: { radius: 0.25, color: '#EF4444' } }; for (var i = currentData.revRange[0]; i <= currentData.revRange[1]; i++) { viewer.setStyle({ chain: 'B', resi: currentData.sequence.length - i }, rs); } } } // Labels if (showLBL) { var seqUpper = currentData.sequence; for (var i = 0; i < Math.min(seqUpper.length, 200); i += 2) { var z = i * currentData.params.rise; var theta = i * (currentData.params.twist * Math.PI / 180); var r = currentData.params.radius - 5.5; var x = r * Math.cos(theta); var y = r * Math.sin(theta); viewer.addLabel(seqUpper[i], { position: { x: x, y: y, z: z }, fontSize: 14, fontColor: baseColors[seqUpper[i]] || '#ffffff', backgroundColor: 'rgba(0,0,0,0.7)', backgroundOpacity: 0.7, padding: 3, borderRadius: 4, font: 'arial' }); } } viewer.render(); } // ─── VIEW PRESETS ────────────────────────────────── function setView(preset) { if (!viewer) return; viewer.zoomTo(); switch (preset) { case 'default': viewer.rotate(90, 'y'); viewer.zoom(1.6); break; case 'major': viewer.rotate(45, 'y'); viewer.zoom(1.4); break; case 'minor': viewer.rotate(-45, 'y'); viewer.zoom(1.4); break; case 'top': viewer.rotate(0, 'y'); viewer.rotate(90, 'x'); viewer.zoom(1.6); break; case 'side': viewer.rotate(90, 'y'); viewer.zoom(1.6); break; } viewer.render(); } function resetView() { if (viewer) { viewer.zoomTo(); viewer.rotate(90, 'y'); viewer.zoom(1.6); viewer.render(); } } // ─── MEASURE ─────────────────────────────────────── function toggleMeasure() { alert('Click-to-measure: select two atoms to measure distance in Å. Coming soon!'); } // ─── STATS DISPLAY ──────────────────────────────── function showStats() { if (!currentData) return; document.getElementById('statsBar').style.display = 'grid'; document.getElementById('sLength').textContent = currentData.stats.helixLength; document.getElementById('sTurns').textContent = currentData.stats.turns; document.getElementById('sAtoms').textContent = currentData.stats.totalAtoms; document.getElementById('sType').textContent = currentData.dnaType; document.getElementById('sFwdPrimer').textContent = currentData.stats.fwdPrimer || '—'; document.getElementById('sRevPrimer').textContent = currentData.stats.revPrimer || '—'; } // ─── EXPORT ──────────────────────────────────────── function exportPNG() { if (!viewer) return; try { var png = viewer.pngURI(); var link = document.createElement('a'); link.download = 'dna-structure-' + getSelectedType().replace('-','') + '.png'; link.href = png; link.click(); } catch (e) { console.error('PNG export failed:', e); alert('PNG export failed. Try a different browser.'); } } function exportPDB() { if (!currentData) return; try { var blob = new Blob([currentData.pdb], { type: 'text/plain' }); var link = document.createElement('a'); link.download = 'dna-structure-' + getSelectedType().replace('-','') + '.pdb'; link.href = URL.createObjectURL(blob); link.click(); URL.revokeObjectURL(link.href); } catch (e) { console.error('PDB export failed:', e); } }
Get Started View Pricing