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="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="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="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>
|
<button type="button" class="astro-conv-tab" data-tab-target="toolsTab" role="tab" aria-selected="false">Diverse Tools</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -517,6 +518,49 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</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">
|
<section class="card astro-conv-panel astro-conv-tab-panel" id="toolsTab" role="tabpanel">
|
||||||
<h2>Diverse Tools</h2>
|
<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>
|
<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'),
|
arcsec: document.getElementById('angleArcsec'),
|
||||||
rad: document.getElementById('angleRad')
|
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 = {
|
const toolFields = {
|
||||||
dateTimeLocal: document.getElementById('toolsDateTimeLocal'),
|
dateTimeLocal: document.getElementById('toolsDateTimeLocal'),
|
||||||
locationName: document.getElementById('toolsLocationName'),
|
locationName: document.getElementById('toolsLocationName'),
|
||||||
@@ -664,6 +716,7 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
|||||||
let timeRequestId = 0;
|
let timeRequestId = 0;
|
||||||
let coordinateRequestId = 0;
|
let coordinateRequestId = 0;
|
||||||
let angleRequestId = 0;
|
let angleRequestId = 0;
|
||||||
|
let antennaRequestId = 0;
|
||||||
let toolRequestId = 0;
|
let toolRequestId = 0;
|
||||||
|
|
||||||
const DECIMAL_DIVISION_PRECISION = 32;
|
const DECIMAL_DIVISION_PRECISION = 32;
|
||||||
@@ -1088,6 +1141,12 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
|||||||
wireTooltipHover(field);
|
wireTooltipHover(field);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const antennaFieldEntries = Object.entries(antennaFields);
|
||||||
|
antennaFieldEntries.forEach(function ([unit, field]) {
|
||||||
|
attachTooltip(field, 'antenna-' + unit);
|
||||||
|
wireTooltipHover(field);
|
||||||
|
});
|
||||||
|
|
||||||
const updateDistanceFrom = async function (sourceUnit) {
|
const updateDistanceFrom = async function (sourceUnit) {
|
||||||
const rawValue = distanceFields[sourceUnit].value.trim();
|
const rawValue = distanceFields[sourceUnit].value.trim();
|
||||||
if (rawValue === '') {
|
if (rawValue === '') {
|
||||||
@@ -1661,6 +1720,98 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
|||||||
updateAngleFrom('arcsec');
|
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 () {
|
const clearToolOutputs = function () {
|
||||||
toolFields.dateTimeUtc.value = '';
|
toolFields.dateTimeUtc.value = '';
|
||||||
toolFields.altitude.value = '';
|
toolFields.altitude.value = '';
|
||||||
@@ -1752,6 +1903,7 @@ $toolDefaultLocalDateTime = (new DateTimeImmutable('now', new DateTimeZone($tool
|
|||||||
updateTimeFrom('utc');
|
updateTimeFrom('utc');
|
||||||
updateCoordinatesFrom('equatorial');
|
updateCoordinatesFrom('equatorial');
|
||||||
updateAngleFrom('deg');
|
updateAngleFrom('deg');
|
||||||
|
updateAntennaFrom('frequencyMhz');
|
||||||
updateSolarTool();
|
updateSolarTool();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user