Mode fond vert : choix du fond apres la photo
- Apres la capture, si chroma key active, une barre de fonds s'affiche avec des miniatures cliquables - L'utilisateur choisit son fond parmi la liste - Remplacement du fond vert en temps reel (OpenCV backend) - Onglet "Fonds verts" dans le backoffice pour importer/supprimer des images de fond - Miniatures visuelles dans l'admin et sur l'ecran de preview Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ async function chargerAdmin() {
|
||||
chargerAnimations();
|
||||
chargerFonctionnalites();
|
||||
chargerEmailAdmin();
|
||||
chargerFondsAdmin();
|
||||
chargerGalerieAdmin();
|
||||
}
|
||||
|
||||
@@ -262,6 +263,55 @@ async function uploaderCadre() {
|
||||
afficherStatut('Cadre importe', 'succes');
|
||||
}
|
||||
|
||||
// === FONDS VERTS ===
|
||||
|
||||
async function chargerFondsAdmin() {
|
||||
const fonds = await apiGet('/api/fonds');
|
||||
const liste = document.getElementById('liste-fonds');
|
||||
liste.innerHTML = '';
|
||||
|
||||
if (fonds.length === 0) {
|
||||
liste.innerHTML = '<p class="texte-secondaire">Aucun fond importe</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
for (const nom of fonds) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'fond-item';
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = `/assets/backgrounds/${nom}`;
|
||||
img.alt = nom;
|
||||
|
||||
const btnSuppr = document.createElement('button');
|
||||
btnSuppr.className = 'btn-supprimer';
|
||||
btnSuppr.innerHTML = '✕';
|
||||
btnSuppr.onclick = () => supprimerFond(nom);
|
||||
|
||||
div.appendChild(img);
|
||||
div.appendChild(btnSuppr);
|
||||
liste.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
async function uploaderFond() {
|
||||
const input = document.getElementById('input-fond');
|
||||
if (!input.files.length) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('fichier', input.files[0]);
|
||||
await fetch('/api/upload/fond', { method: 'POST', body: formData });
|
||||
input.value = '';
|
||||
chargerFondsAdmin();
|
||||
afficherStatut('Fond importe', 'succes');
|
||||
}
|
||||
|
||||
async function supprimerFond(nom) {
|
||||
if (!confirm(`Supprimer le fond "${nom}" ?`)) return;
|
||||
await fetch(`/api/fonds/${encodeURIComponent(nom)}`, { method: 'DELETE' });
|
||||
chargerFondsAdmin();
|
||||
}
|
||||
|
||||
// === ANIMATIONS ===
|
||||
|
||||
const EMOJI_MAP = { 3: '🤪', 2: '😱', 1: '🔥' };
|
||||
|
||||
@@ -208,6 +208,9 @@ function afficherPreviewPhoto(chemin) {
|
||||
if (config.fonctionnalites?.overlays) {
|
||||
chargerOverlays();
|
||||
}
|
||||
if (config.fonctionnalites?.chroma_key) {
|
||||
chargerFonds();
|
||||
}
|
||||
}
|
||||
|
||||
// --- Compteur accueil ---
|
||||
|
||||
71
frontend/js/effects.js
vendored
71
frontend/js/effects.js
vendored
@@ -1,7 +1,8 @@
|
||||
/* Module effets - Filtres et overlays */
|
||||
/* Module effets - Filtres, overlays et fond vert */
|
||||
|
||||
let filtreActuel = 'original';
|
||||
let overlayActuel = null;
|
||||
let fondActuel = null;
|
||||
|
||||
async function chargerFiltres() {
|
||||
const filtres = await apiGet('/api/filtres');
|
||||
@@ -18,7 +19,6 @@ async function chargerFiltres() {
|
||||
}
|
||||
|
||||
async function appliquerFiltreUI(filtre, btn) {
|
||||
// Activer visuellement
|
||||
document.querySelectorAll('.btn-filtre').forEach(b => b.classList.remove('actif'));
|
||||
btn.classList.add('actif');
|
||||
filtreActuel = filtre;
|
||||
@@ -55,7 +55,6 @@ async function chargerOverlays() {
|
||||
barre.classList.remove('cache');
|
||||
barre.innerHTML = '';
|
||||
|
||||
// Bouton "sans overlay"
|
||||
const btnAucun = document.createElement('button');
|
||||
btnAucun.className = 'btn-overlay actif';
|
||||
btnAucun.textContent = 'Sans cadre';
|
||||
@@ -91,7 +90,71 @@ function retirerOverlay(btn) {
|
||||
btn.classList.add('actif');
|
||||
overlayActuel = null;
|
||||
|
||||
// Revenir a la photo avec filtre actuel (ou originale)
|
||||
if (filtreActuel !== 'original') {
|
||||
appliquerFiltreUI(filtreActuel, document.querySelector('.btn-filtre.actif'));
|
||||
} else {
|
||||
const chemin = '/data/photos/' + photosSession[0];
|
||||
document.getElementById('photo-resultat').src = chemin;
|
||||
document.getElementById('photo-partage').src = chemin;
|
||||
photoFinale = photosSession[0];
|
||||
}
|
||||
}
|
||||
|
||||
// === Fond vert (chroma key) ===
|
||||
|
||||
async function chargerFonds() {
|
||||
const fonds = await apiGet('/api/fonds');
|
||||
const barre = document.getElementById('barre-fonds');
|
||||
|
||||
if (!config.fonctionnalites?.chroma_key || fonds.length === 0) {
|
||||
barre.classList.add('cache');
|
||||
return;
|
||||
}
|
||||
|
||||
barre.classList.remove('cache');
|
||||
barre.innerHTML = '';
|
||||
fondActuel = null;
|
||||
|
||||
// Bouton "original" (pas de chroma key)
|
||||
const btnOriginal = document.createElement('button');
|
||||
btnOriginal.className = 'btn-fond actif';
|
||||
btnOriginal.innerHTML = '<span style="font-size:0.7rem;color:var(--texte-secondaire)">Original</span>';
|
||||
btnOriginal.addEventListener('click', () => retirerFond(btnOriginal));
|
||||
barre.appendChild(btnOriginal);
|
||||
|
||||
for (const nom of fonds) {
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'btn-fond';
|
||||
const img = document.createElement('img');
|
||||
img.src = `/assets/backgrounds/${nom}`;
|
||||
img.alt = nom;
|
||||
btn.appendChild(img);
|
||||
btn.addEventListener('click', () => appliquerFondUI(nom, btn));
|
||||
barre.appendChild(btn);
|
||||
}
|
||||
}
|
||||
|
||||
async function appliquerFondUI(nom, btn) {
|
||||
document.querySelectorAll('.btn-fond').forEach(b => b.classList.remove('actif'));
|
||||
btn.classList.add('actif');
|
||||
fondActuel = nom;
|
||||
|
||||
const photo = photosSession[0];
|
||||
const resultat = await apiPost('/api/chroma', { photo, fond: nom });
|
||||
|
||||
if (resultat.nom) {
|
||||
photoFinale = resultat.nom;
|
||||
document.getElementById('photo-resultat').src = '/data/exports/' + resultat.nom;
|
||||
document.getElementById('photo-partage').src = '/data/exports/' + resultat.nom;
|
||||
}
|
||||
}
|
||||
|
||||
function retirerFond(btn) {
|
||||
document.querySelectorAll('.btn-fond').forEach(b => b.classList.remove('actif'));
|
||||
btn.classList.add('actif');
|
||||
fondActuel = null;
|
||||
|
||||
// Revenir a la photo originale ou avec filtre
|
||||
if (filtreActuel !== 'original') {
|
||||
appliquerFiltreUI(filtreActuel, document.querySelector('.btn-filtre.actif'));
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user