:root {
–primary-color: #3498db;
–secondary-color: #2c3e50;
–accent-color: #e74c3c;
–light-color: #ecf0f1;
–dark-color: #2c3e50;
–text-color: #333;
–card-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
–hover-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
–transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif;
background-color: #f8f9fa;
color: var(–text-color);
line-height: 1.6;
overflow-x: hidden;
}
/* Header Styles */
header {
background: linear-gradient(135deg, var(–primary-color), var(–secondary-color));
color: white;
padding: 1rem 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
position: sticky;
top: 0;
z-index: 1000;
}
.header-container {
width: 90%;
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center; /* Alinha verticalmente ao centro */
gap: 12px; /* Espaço entre ícone e título (ajuste livre) */
}
.logo i {
font-size: 1.5rem; /* Tamanho do ícone */
display: flex;
align-items: center; /* Se for FontAwesome, pode ajudar */
height: 1.5rem; /* Mantém a altura igual ao h1, ajuste se precisar */
}
.logo h1 {
font-size: 1.5rem;
font-weight: 600;
display: flex;
align-items: center; /* Garante alinhamento com o ícone também */
height: 1.5rem; /* Igual ao ícone para alinhar perfeitamente */
margin: 0; /* Remove margem padrão do h1 */
line-height: 1.5rem; /* Garante alinhamento vertical */
}
/* Main Content */
.container {
width: 90%;
max-width: 800px;
margin: 2rem auto;
padding: 2rem 0;
}
/* Calculator Container */
.calculator-container {
background: white;
border-radius: 15px;
box-shadow: var(–card-shadow);
padding: 2rem;
position: relative;
overflow: hidden;
}
.calculator-container::before {
content: ”;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: linear-gradient(90deg, var(–primary-color), var(–accent-color));
}
.calculator-header {
text-align: center;
margin-bottom: 2rem;
}
.calculator-header img {
max-width: 200px;
border-radius: 10px;
margin-bottom: 1rem;
box-shadow: var(–card-shadow);
}
.calculator-header h2 {
color: var(–secondary-color);
margin-bottom: 0.5rem;
font-size: 2rem;
}
.calculator-header p {
color: #666;
font-size: 1rem;
}
/* Form Section */
.form-section {
margin-bottom: 2rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
font-weight: 600;
margin-bottom: 0.5rem;
color: var(–secondary-color);
}
.waveform-buttons {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-bottom: 1.5rem;
}
.waveform-btn {
padding: 0.75rem;
border: none;
border-radius: 10px;
font-weight: 600;
cursor: pointer;
transition: var(–transition);
background: linear-gradient(135deg, var(–primary-color), #2980b9);
color: white;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.waveform-btn:hover {
transform: translateY(-3px);
box-shadow: var(–hover-shadow);
background: linear-gradient(135deg, #2980b9, var(–primary-color));
}
.waveform-btn.active {
background: linear-gradient(135deg, var(–accent-color), #c0392b);
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(231, 76, 60, 0); }
100% { box-shadow: 0 0 0 0 rgba(231, 76, 60, 0); }
}
.input-group {
display: flex;
align-items: center;
margin-bottom: 1rem;
}
.input-group input[type=”number”] {
flex: 1;
padding: 0.75rem;
border: 2px solid #e9ecef;
border-radius: 10px;
font-size: 1rem;
transition: var(–transition);
}
.input-group input[type=”number”]:focus {
outline: none;
border-color: var(–primary-color);
box-shadow: 0 0 0 0.2rem rgba(52, 152, 219, 0.25);
}
.input-group input[type=”range”] {
flex: 1;
margin: 0 1rem;
}
.value-display {
min-width: 80px;
text-align: center;
font-weight: 600;
color: var(–primary-color);
}
/* Controls Section */
.controls {
display: flex;
gap: 1rem;
margin-top: 2rem;
flex-wrap: wrap;
}
.btn {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 10px;
font-weight: 600;
cursor: pointer;
transition: var(–transition);
display: flex;
align-items: center;
gap: 0.5rem;
}
.btn-play {
background: linear-gradient(135deg, #27ae60, #2ecc71);
color: white;
}
.btn-play:hover {
transform: translateY(-3px);
box-shadow: var(–hover-shadow);
background: linear-gradient(135deg, #2ecc71, #27ae60);
}
.btn-reset {
background: linear-gradient(135deg, #6c757d, #5a6268);
color: white;
}
.btn-reset:hover {
transform: translateY(-3px);
box-shadow: var(–hover-shadow);
background: linear-gradient(135deg, #5a6268, #6c757d);
}
.btn-tools {
background: linear-gradient(135deg, var(–primary-color), #2980b9);
color: white;
}
.btn-tools:hover {
transform: translateY(-3px);
box-shadow: var(–hover-shadow);
background: linear-gradient(135deg, #2980b9, var(–primary-color));
}
/* Footer Message */
.footer-message {
background: #f8f9fa;
border-radius: 10px;
padding: 1rem;
margin-top: 2rem;
color: #6c757d;
font-size: 0.9rem;
text-align: justify;
}
/* Animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Responsive Design */
@media (max-width: 768px) {
.calculator-container {
padding: 1.5rem;
}
.calculator-header h2 {
font-size: 1.5rem;
}
.waveform-buttons {
grid-template-columns: repeat(2, 1fr);
}
.controls {
flex-direction: column;
}
.btn {
width: 100%;
justify-content: center;
}
}
@media (max-width: 480px) {
.calculator-container {
padding: 1rem;
}
.calculator-header h2 {
font-size: 1.3rem;
}
.waveform-buttons {
grid-template-columns: 1fr;
}
}
Ferramentas Online
Gerador de Ondas Sonoras
Senoide, Quadrada, Triangular, Dente de Serra, Ruído Rosa e Ruído Branco
var activeWaveform = ‘sine’;
var audioContext = new (window.AudioContext || window.webkitAudioContext)();
var oscillator = null;
var gainNode = audioContext.createGain();
var panNode = audioContext.createStereoPanner();
function selectWaveform(waveform) {
activeWaveform = waveform;
var buttons = document.querySelectorAll(‘.waveform-btn’);
buttons.forEach(function(button) {
button.classList.remove(‘active’);
});
document.getElementById(waveform).classList.add(‘active’);
// Desabilita controles de frequência para ruídos
const frequencyControls = document.getElementById(‘frequency’);
const frequencySlider = document.getElementById(‘frequencySlider’);
if (waveform === ‘white’ || waveform === ‘pink’) {
frequencyControls.disabled = true;
frequencySlider.disabled = true;
} else {
frequencyControls.disabled = false;
frequencySlider.disabled = false;
}
if (oscillator) {
oscillator.stop();
oscillator.disconnect();
oscillator = null;
document.getElementById(‘playStop’).innerHTML = ‘Play/Stop’;
}
}
function updateFrequency() {
if (activeWaveform !== ‘white’ && activeWaveform !== ‘pink’) {
var frequency = document.getElementById(‘frequency’).value;
document.getElementById(‘frequencySlider’).value = frequency;
document.getElementById(‘frequencyValue’).textContent = frequency + ‘ Hz’;
if (oscillator && oscillator.frequency) {
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
}
}
}
function updateFrequencySlider() {
var frequency = document.getElementById(‘frequencySlider’).value;
document.getElementById(‘frequency’).value = frequency;
document.getElementById(‘frequencyValue’).textContent = frequency + ‘ Hz’;
if (oscillator) {
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
}
}
function updateBalance() {
var balance = document.getElementById(‘balance’).value;
document.getElementById(‘balanceValue’).textContent = balance + ‘%’;
panNode.pan.setValueAtTime(balance / 100, audioContext.currentTime);
}
function updateVolume() {
var volume = document.getElementById(‘volume’).value;
document.getElementById(‘volumeValue’).textContent = volume + ‘%’;
gainNode.gain.setValueAtTime(volume / 100, audioContext.currentTime);
}
function toggleAudio() {
if (oscillator) {
oscillator.stop();
oscillator.disconnect();
oscillator = null;
document.getElementById(‘playStop’).innerHTML = ‘Play/Stop’;
} else {
if (activeWaveform === ‘white’) {
oscillator = createWhiteNoise(audioContext);
} else if (activeWaveform === ‘pink’) {
oscillator = createPinkNoise(audioContext);
} else {
oscillator = audioContext.createOscillator();
oscillator.type = activeWaveform;
var frequency = document.getElementById(‘frequency’).value;
oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime);
}
oscillator.connect(panNode);
panNode.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.start();
document.getElementById(‘playStop’).innerHTML = ‘Play/Stop’;
}
}
function resetSettings() {
selectWaveform(‘sine’);
document.getElementById(‘frequency’).value = 440;
document.getElementById(‘frequencySlider’).value = 440;
document.getElementById(‘balance’).value = 0;
document.getElementById(‘volume’).value = 50;
document.getElementById(‘frequencyValue’).textContent = ‘440 Hz’;
document.getElementById(‘balanceValue’).textContent = ‘0%’;
document.getElementById(‘volumeValue’).textContent = ‘50%’;
if (oscillator) {
oscillator.stop();
oscillator.disconnect();
oscillator = null;
document.getElementById(‘playStop’).innerHTML = ‘Play/Stop’;
}
}
// Função para gerar ruído branco
function createWhiteNoise(audioContext) {
const bufferSize = 2 * audioContext.sampleRate;
const noiseBuffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate);
const output = noiseBuffer.getChannelData(0);
for (let i = 0; i < bufferSize; i++) {
output[i] = Math.random() * 2 – 1;
}
const whiteNoise = audioContext.createBufferSource();
whiteNoise.buffer = noiseBuffer;
whiteNoise.loop = true;
return whiteNoise;
}
// Função para gerar ruído rosa
function createPinkNoise(audioContext) {
const bufferSize = 2 * audioContext.sampleRate;
const noiseBuffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate);
const output = noiseBuffer.getChannelData(0);
let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0;
for (let i = 0; i < bufferSize; i++) {
const white = Math.random() * 2 – 1;
b0 = 0.99886 * b0 + white * 0.0555179;
b1 = 0.99332 * b1 + white * 0.0750759;
b2 = 0.96900 * b2 + white * 0.1538520;
b3 = 0.86650 * b3 + white * 0.3104856;
b4 = 0.55000 * b4 + white * 0.5329522;
b5 = -0.7616 * b5 – white * 0.0168980;
output[i] = b0 + b1 + b2 + b3 + b4 + b5;
output[i] *= 0.11;
}
const pinkNoise = audioContext.createBufferSource();
pinkNoise.buffer = noiseBuffer;
pinkNoise.loop = true;
return pinkNoise;
}
English
Español