Add antenna conversion tab
This commit is contained in:
@@ -246,6 +246,7 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="timeTab" role="tab" aria-selected="false">Zeit</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="coordinatesTab" role="tab" aria-selected="false">Koordinaten</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="angleTab" role="tab" aria-selected="false">Winkel</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="antennaTab" role="tab" aria-selected="false">Antennen</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="toolsTab" role="tab" aria-selected="false">Diverse Tools</button>
|
||||
</div>
|
||||
|
||||
@@ -517,6 +518,49 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card astro-conv-panel astro-conv-tab-panel" id="antennaTab" role="tabpanel">
|
||||
<h2>Antennen-Umrechner</h2>
|
||||
<p>Frequenz und Wellenlaenge ineinander umrechnen sowie Richtwerte fuer einen Halbwellendipol berechnen.</p>
|
||||
|
||||
<div class="astro-conv-grid" id="antennaConverter">
|
||||
<div class="astro-conv-field">
|
||||
<label for="antennaFrequencyMhz">Frequenz (MHz)</label>
|
||||
<input class="astro-conv-input" id="antennaFrequencyMhz" type="text" inputmode="decimal" value="145">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="antennaWavelengthM">Wellenlaenge (m)</label>
|
||||
<input class="astro-conv-input" id="antennaWavelengthM" type="text" inputmode="decimal">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="antennaWavelengthCm">Wellenlaenge (cm)</label>
|
||||
<input class="astro-conv-input" id="antennaWavelengthCm" type="text" readonly>
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="antennaHalfwaveTotalM"><span class="astro-conv-label-help" title="Theoretische Gesamtlaenge eines Halbwellendipols: Lambda / 2.">Dipol gesamt theoretisch (m)</span></label>
|
||||
<input class="astro-conv-input" id="antennaHalfwaveTotalM" type="text" readonly>
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="antennaHalfwavePracticalM"><span class="astro-conv-label-help" title="Praxisnaher Richtwert mit Verkuerzungsfaktor 0,95 fuer einen einfachen Drahtdipol.">Dipol gesamt praktisch (m)</span></label>
|
||||
<input class="astro-conv-input" id="antennaHalfwavePracticalM" type="text" readonly>
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="antennaLegLengthM"><span class="astro-conv-label-help" title="Laenge eines einzelnen Dipol-Schenkels. Praktischer Richtwert: Lambda x 0,95 / 4.">Ein Schenkel (m)</span></label>
|
||||
<input class="astro-conv-input" id="antennaLegLengthM" type="text" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-actions">
|
||||
<button type="button" class="btn btn-secondary" id="antennaClear">Leeren</button>
|
||||
<button type="button" class="btn btn-primary" id="antenna2m">2-m-Band</button>
|
||||
<button type="button" class="btn btn-primary" id="antennaCb">CB-Funk</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card astro-conv-panel astro-conv-tab-panel" id="toolsTab" role="tabpanel">
|
||||
<h2>Diverse Tools</h2>
|
||||
<p>Sonnenstand für den Standard-Standort aus dem Header berechnen. Datum und Uhrzeit werden in der lokalen Zeitzone des Standorts interpretiert.</p>
|
||||
@@ -647,6 +691,14 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
arcsec: document.getElementById('angleArcsec'),
|
||||
rad: document.getElementById('angleRad')
|
||||
};
|
||||
const antennaFields = {
|
||||
frequencyMhz: document.getElementById('antennaFrequencyMhz'),
|
||||
wavelengthM: document.getElementById('antennaWavelengthM'),
|
||||
wavelengthCm: document.getElementById('antennaWavelengthCm'),
|
||||
halfwaveTotalM: document.getElementById('antennaHalfwaveTotalM'),
|
||||
halfwavePracticalM: document.getElementById('antennaHalfwavePracticalM'),
|
||||
legLengthM: document.getElementById('antennaLegLengthM')
|
||||
};
|
||||
const toolFields = {
|
||||
dateTimeLocal: document.getElementById('toolsDateTimeLocal'),
|
||||
locationName: document.getElementById('toolsLocationName'),
|
||||
@@ -664,6 +716,7 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
let timeRequestId = 0;
|
||||
let coordinateRequestId = 0;
|
||||
let angleRequestId = 0;
|
||||
let antennaRequestId = 0;
|
||||
let toolRequestId = 0;
|
||||
|
||||
const DECIMAL_DIVISION_PRECISION = 32;
|
||||
@@ -1088,6 +1141,12 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
wireTooltipHover(field);
|
||||
});
|
||||
|
||||
const antennaFieldEntries = Object.entries(antennaFields);
|
||||
antennaFieldEntries.forEach(function ([unit, field]) {
|
||||
attachTooltip(field, 'antenna-' + unit);
|
||||
wireTooltipHover(field);
|
||||
});
|
||||
|
||||
const updateDistanceFrom = async function (sourceUnit) {
|
||||
const rawValue = distanceFields[sourceUnit].value.trim();
|
||||
if (rawValue === '') {
|
||||
@@ -1661,6 +1720,98 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
updateAngleFrom('arcsec');
|
||||
});
|
||||
|
||||
const formatNumber = function (value, maxFractionDigits) {
|
||||
if (!Number.isFinite(value)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return value.toLocaleString('de-DE', {
|
||||
maximumFractionDigits: maxFractionDigits,
|
||||
useGrouping: true
|
||||
});
|
||||
};
|
||||
|
||||
const clearAntennaOutputs = function () {
|
||||
['wavelengthCm', 'halfwaveTotalM', 'halfwavePracticalM', 'legLengthM'].forEach(function (key) {
|
||||
antennaFields[key].value = '';
|
||||
updateTooltip(antennaFields[key]);
|
||||
});
|
||||
};
|
||||
|
||||
const updateAntennaFrom = function (sourceUnit) {
|
||||
const sourceField = antennaFields[sourceUnit];
|
||||
if (!sourceField) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rawValue = sourceField.value.trim();
|
||||
if (rawValue === '') {
|
||||
Object.entries(antennaFields).forEach(function ([key, field]) {
|
||||
if (key !== sourceUnit) {
|
||||
field.value = '';
|
||||
updateTooltip(field);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedValue = parseDecimalInput(rawValue);
|
||||
const numericValue = parsedValue ? decimalToNumber(parsedValue) : Number.NaN;
|
||||
if (!Number.isFinite(numericValue) || numericValue <= 0) {
|
||||
clearAntennaOutputs();
|
||||
return;
|
||||
}
|
||||
|
||||
const requestId = ++antennaRequestId;
|
||||
const wavelengthMeters = sourceUnit === 'frequencyMhz'
|
||||
? 299.792458 / numericValue
|
||||
: numericValue;
|
||||
const frequencyMhz = sourceUnit === 'wavelengthM'
|
||||
? 299.792458 / numericValue
|
||||
: numericValue;
|
||||
|
||||
if (requestId !== antennaRequestId || !Number.isFinite(wavelengthMeters) || wavelengthMeters <= 0) {
|
||||
clearAntennaOutputs();
|
||||
return;
|
||||
}
|
||||
|
||||
const practicalFactor = 0.95;
|
||||
antennaFields.frequencyMhz.value = formatNumber(frequencyMhz, 6);
|
||||
antennaFields.wavelengthM.value = formatNumber(wavelengthMeters, 6);
|
||||
antennaFields.wavelengthCm.value = formatNumber(wavelengthMeters * 100, 2);
|
||||
antennaFields.halfwaveTotalM.value = formatNumber(wavelengthMeters / 2, 4);
|
||||
antennaFields.halfwavePracticalM.value = formatNumber((wavelengthMeters / 2) * practicalFactor, 4);
|
||||
antennaFields.legLengthM.value = formatNumber((wavelengthMeters / 4) * practicalFactor, 4);
|
||||
|
||||
Object.values(antennaFields).forEach(function (field) {
|
||||
updateTooltip(field);
|
||||
});
|
||||
};
|
||||
|
||||
['frequencyMhz', 'wavelengthM'].forEach(function (key) {
|
||||
antennaFields[key].addEventListener('input', function () {
|
||||
updateAntennaFrom(key);
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('antennaClear').addEventListener('click', function () {
|
||||
Object.values(antennaFields).forEach(function (field) {
|
||||
field.value = '';
|
||||
updateTooltip(field);
|
||||
});
|
||||
antennaFields.frequencyMhz.focus();
|
||||
});
|
||||
|
||||
document.getElementById('antenna2m').addEventListener('click', function () {
|
||||
antennaFields.frequencyMhz.value = '145';
|
||||
updateAntennaFrom('frequencyMhz');
|
||||
});
|
||||
|
||||
document.getElementById('antennaCb').addEventListener('click', function () {
|
||||
antennaFields.frequencyMhz.value = '27,2';
|
||||
updateAntennaFrom('frequencyMhz');
|
||||
});
|
||||
|
||||
const clearToolOutputs = function () {
|
||||
toolFields.dateTimeUtc.value = '';
|
||||
toolFields.altitude.value = '';
|
||||
@@ -1752,6 +1903,7 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
||||
updateTimeFrom('utc');
|
||||
updateCoordinatesFrom('equatorial');
|
||||
updateAngleFrom('deg');
|
||||
updateAntennaFrom('frequencyMhz');
|
||||
updateSolarTool();
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user