Refactor camera configuration UI and enhance live preview functionality
This commit is contained in:
parent
7ea52bc571
commit
7d9360576f
|
|
@ -7,38 +7,43 @@
|
||||||
<form id="camera-config-form">
|
<form id="camera-config-form">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column is-half">
|
<div class="column is-half">
|
||||||
{% for group in grouped_params %}
|
<div id="camera-config-container"></div>
|
||||||
<div class="box">
|
|
||||||
<h2 class="subtitle has-text-weight-bold">
|
|
||||||
{{ group.section | replace('settings', ' Settings') | capitalize }}
|
|
||||||
</h2>
|
|
||||||
{% for param in group.params %}
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="{{ param.name }}">{{ param.label }}:</label>
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select id="{{ param.name }}" name="{{ param.name }}">
|
|
||||||
{% for choice in param.choices %}
|
|
||||||
<option value="{{ choice.value }}" {% if choice.label == param.current %}selected{% endif %}>
|
|
||||||
{{ choice.label }} ({{ choice.value }})
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control mt-2">
|
|
||||||
<button class="button is-small is-primary" type="button" onclick="setConfig('{{ param.name }}')">Set</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="column is-half has-text-centered">
|
<div class="column is-half has-text-centered">
|
||||||
<figure class="image is-4by3" style="max-width: 480px; margin: auto;">
|
<figure class="image is-4by3" style="max-width: 480px; margin: auto;">
|
||||||
<img id="camera-preview" src="/camera/feed.jpg?{{ range(1000000)|random }}" alt="Camera Preview" style="border: 1px solid #ccc;">
|
<img id="camera-preview" src="/camera/feed.jpg?{{ range(1000000)|random }}" alt="Camera Preview"
|
||||||
|
style="border: 1px solid #ccc;">
|
||||||
</figure>
|
</figure>
|
||||||
<button class="button is-small is-info mt-2" type="button" onclick="refreshPreview()">Rafraîchir l’aperçu</button>
|
|
||||||
|
|
||||||
|
<nav class="level">
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Speed</p>
|
||||||
|
<p id="display-camera-shutterspeed" class="title is-5">Updating ...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">f/</p>
|
||||||
|
<p id="display-camera-aperture" class="title is-5"> Updating ...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">ISO</p>
|
||||||
|
<p id="display-camera-iso" class="title is-5">Updating ...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">°K</p>
|
||||||
|
<p id="display-camera-color-temperature" class="title is-5">Updating ...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<button class="button is-small is-info mt-2" type="button" onclick="refreshPreview()">Rafraîchir
|
||||||
|
l’aperçu</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -48,27 +53,88 @@
|
||||||
|
|
||||||
{% block extrajs %}
|
{% block extrajs %}
|
||||||
<script>
|
<script>
|
||||||
function setConfig(paramName) {
|
function setConfig(paramName) {
|
||||||
const value = document.getElementById(paramName).value;
|
const value = document.getElementById(paramName).value;
|
||||||
fetch('/camera/set', {
|
fetch('/camera/set', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ [paramName]: value })
|
body: JSON.stringify({ [paramName]: value })
|
||||||
}).then(() => location.reload());
|
}).then(() => location.reload());
|
||||||
}
|
}
|
||||||
|
|
||||||
window.refreshPreview = function() {
|
window.refreshPreview = function () {
|
||||||
const img = document.getElementById('camera-preview');
|
const img = document.getElementById('camera-preview');
|
||||||
const url = '/camera/feed.jpg?' + new Date().getTime();
|
const url = '/camera/feed.jpg?' + new Date().getTime();
|
||||||
img.src = url;
|
img.src = url;
|
||||||
}
|
}
|
||||||
//setInterval(window.refreshPreview, 2000);
|
//setInterval(window.refreshPreview, 2000);
|
||||||
|
|
||||||
fetch('/camera/config')
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
.then(response => response.json())
|
fetch('/camera/config')
|
||||||
.then(data => {
|
.then(response => response.json())
|
||||||
// data is grouped_params, you can now dynamically build selects in JS
|
.then(data => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
});
|
// data is grouped_params
|
||||||
|
const container = document.getElementById('camera-config-container');
|
||||||
|
container.innerHTML = '';
|
||||||
|
const captureSection = data.find(group => group.section === 'capturesettings');
|
||||||
|
if (captureSection) {
|
||||||
|
// Find the shutterspeed param
|
||||||
|
const shutterParam = captureSection.params.find(param => param.name === 'shutterspeed');
|
||||||
|
if (shutterParam) {
|
||||||
|
document.getElementById('display-camera-shutterspeed').textContent = shutterParam.current;
|
||||||
|
}
|
||||||
|
// find the aperture param
|
||||||
|
const apertureParam = captureSection.params.find(param => param.name === 'aperture');
|
||||||
|
if (apertureParam) {
|
||||||
|
document.getElementById('display-camera-aperture').textContent = apertureParam.current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const imgSection = data.find(group => group.section === 'imgsettings');
|
||||||
|
if (imgSection) {
|
||||||
|
// Find the iso param
|
||||||
|
const isoParam = imgSection.params.find(param => param.name === 'iso');
|
||||||
|
if (isoParam) {
|
||||||
|
document.getElementById('display-camera-iso').textContent = isoParam.current;
|
||||||
|
}
|
||||||
|
// find the whitebalance param
|
||||||
|
const wbParam = imgSection.params.find(param => param.name === 'colortemperature');
|
||||||
|
if (wbParam) {
|
||||||
|
document.getElementById('display-camera-color-temperature').textContent = wbParam.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data.forEach(group => {
|
||||||
|
const box = document.createElement('div');
|
||||||
|
box.className = 'box';
|
||||||
|
box.innerHTML = `<h2 class="subtitle has-text-weight-bold">${group.section.replace('settings', ' Settings')}</h2>`;
|
||||||
|
group.params.forEach(param => {
|
||||||
|
let field = document.createElement('div');
|
||||||
|
field.className = 'field';
|
||||||
|
field.innerHTML = `
|
||||||
|
<label class="label" for="${param.name}">${param.label}:</label>
|
||||||
|
<div class="control">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select id="${param.name}" name="${param.name}">
|
||||||
|
${param.choices.map(choice =>
|
||||||
|
`<option value="${choice.value}" ${choice.label === param.current ? 'selected' : ''}>
|
||||||
|
${choice.label} (${choice.value})
|
||||||
|
</option>`
|
||||||
|
).join('')}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control mt-2">
|
||||||
|
<button class="button is-small is-primary" type="button" onclick="setConfig('${param.name}')">Set</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
box.appendChild(field);
|
||||||
|
});
|
||||||
|
container.appendChild(box);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock extrajs %}
|
{% endblock extrajs %}
|
||||||
Loading…
Reference in New Issue