475 lines
17 KiB
JavaScript
475 lines
17 KiB
JavaScript
/**
|
|
* définition des constantes
|
|
*/
|
|
let personnes = [], nom = [], nomjf = [], prenom = [], annee = [], note = [], posx = [], posy = [], etx = [], ety = [],
|
|
can_etiq = [];
|
|
let ibac = 0, tit = {}, titre = "", fond = [];
|
|
let mode_saisie = "true" // mode saisie true, mode modification false
|
|
let image = document.getElementById('ima_fond');
|
|
const cercle = document.getElementById("circle_svg");
|
|
let menu = document.getElementById("menu_modif");
|
|
let modif_titre = document.getElementById("nouveau_titre");
|
|
let canevas_photo = document.createElement("canvas");
|
|
document.body.appendChild(canevas_photo);
|
|
let nb_pers = 0;
|
|
|
|
/**
|
|
* écoute du changement de l'input fichier pour charger la photo
|
|
* @type {HTMLElement}
|
|
*/
|
|
let inputElement = document.getElementById('fichiers');
|
|
inputElement.addEventListener('change', (e) => {
|
|
lecture_photo(e.target.files)
|
|
}, false);
|
|
|
|
function lecture_photo(fichier) {
|
|
nb_fichier = fichier.length
|
|
let i_xml = 1, i_img = 0;
|
|
if (fichier[0].name.split('.').pop() == "xml") {
|
|
i_xml = 0;
|
|
i_img = 1
|
|
}
|
|
|
|
let src = fichier[i_img].name.substring(0, fichier[i_img].name.indexOf("."));
|
|
enreg_xml = src + ".xml"
|
|
enreg_noms = src + "_noms.png"
|
|
fichier_xml = fichier[i_xml];
|
|
fond = fichier[i_img];
|
|
affiche_fond();
|
|
|
|
// Un seul fichier sélectionné : l'image à traiter
|
|
if (nb_fichier == 1) {
|
|
creation_data_xml();
|
|
lecture_xml();
|
|
return
|
|
}
|
|
|
|
// deux fichiers selectionnés : l'image et haarcascade.xml
|
|
if (fichier_xml.name.startsWith("haar")) {
|
|
creation_data_xml();
|
|
detection_de_visages();
|
|
return
|
|
}
|
|
|
|
// deux fichiers selectionnés : l'image et le xml du même nom
|
|
let reader = new FileReader();
|
|
reader.onload = function (evt) {
|
|
lecture(evt.target.result);
|
|
};
|
|
reader.readAsText(fichier_xml);
|
|
|
|
function lecture(text) {
|
|
let parser = new DOMParser();
|
|
data_xml = parser.parseFromString(text, "text/xml");
|
|
lecture_xml();
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Chargement et affichage de l'image background
|
|
*/
|
|
function affiche_fond() {
|
|
let read_fond = new FileReader();
|
|
read_fond.addEventListener("load", function (evt) {
|
|
image.src = evt.target.result;
|
|
|
|
console.log('image', image, image.offsetLeft, image.offsetTop);
|
|
}, false);
|
|
read_fond.readAsDataURL(fond);
|
|
}
|
|
|
|
function lecture_xml() {
|
|
tit = data_xml.documentElement.getElementsByTagName("titre")[0];
|
|
titre = tit.textContent
|
|
personnes = data_xml.documentElement.getElementsByTagName("personne");
|
|
nb_pers = personnes.length
|
|
|
|
console.log('image', image, image.offsetLeft, image.offsetTop);
|
|
|
|
for (let i = 0; i < nb_pers; i++) {
|
|
nom[i] = personnes[i].getElementsByTagName("nom")[0].textContent;
|
|
if (personnes[i].getElementsByTagName("nom_jeune_fille")[0]) {
|
|
nomjf[i] = personnes[i].getElementsByTagName("nom_jeune_fille")[0].textContent;
|
|
}
|
|
prenom[i] = personnes[i].getElementsByTagName("prenom")[0].textContent;
|
|
annee[i] = personnes[i].getElementsByTagName("annee_naiss")[0].textContent;
|
|
note[i] = personnes[i].getElementsByTagName("note")[0].textContent;
|
|
posx[i] = parseFloat(personnes[i].getElementsByTagName("position")[0].attributes['posx'].value + image.offsetLeft);
|
|
posy[i] = parseFloat(personnes[i].getElementsByTagName("position")[0].attributes['posy'].value + image.offsetTop);
|
|
etx[i] = parseFloat(personnes[i].getElementsByTagName("position")[0].attributes['etx'].value + image.offsetLeft);
|
|
ety[i] = parseFloat(personnes[i].getElementsByTagName("position")[0].attributes['ety'].value + image.offsetTop);
|
|
}
|
|
if (titre !== '') {
|
|
affiche_titre(titre)
|
|
}
|
|
affiche_etiquette();
|
|
};
|
|
|
|
function affiche_titre(titre_photo) {
|
|
canevas_photo.className = "titre";
|
|
canevas_photo.height = 23;
|
|
let taille = titre_photo.length;
|
|
canevas_photo.width = taille * 12;
|
|
tx = parseFloat(tit.attributes['titx'].value + image.offsetLeft);
|
|
ty = parseFloat(tit.attributes['tity'].value + image.offsetTop);
|
|
canevas_photo.style.left = tx + "px";
|
|
canevas_photo.style.top = ty + "px";
|
|
titre_ctx = canevas_photo.getContext("2d");
|
|
titre_ctx.fillText(titre_photo, 20, 18);
|
|
affiche_etiquette();
|
|
}
|
|
|
|
/**
|
|
* affichage du texte nom/prénom dans des canvas etiquette
|
|
*/
|
|
function affiche_etiquette() {
|
|
rayon = 28
|
|
for (let i = 0; i < nb_pers; i++) {
|
|
let id = "can" + i;
|
|
if (document.getElementById(id)) continue;
|
|
let canv = document.createElement("canvas");
|
|
canv.id = id;
|
|
canv.setAttribute('class', 'people_label')
|
|
document.body.appendChild(canv);
|
|
can_etiq[i] = document.getElementById(canv.id);
|
|
can_etiq[i].className = "etiq";
|
|
can_etiq[i].height = 30;
|
|
etiq_ctx = can_etiq[i].getContext("2d");
|
|
let taille = Math.max(nom[i].length, prenom[i].length, nomjf[i].length + 5);
|
|
can_etiq[i].width = taille * 7 + 10
|
|
if (nomjf[i].replace(/\t/g, '').length > 1) {
|
|
can_etiq[i].height = 45
|
|
}
|
|
;
|
|
can_etiq[i].style.left = etx[i] + "px";
|
|
can_etiq[i].style.top = ety[i] + "px";
|
|
etiq_ctx.fillText(nom[i], 7, 12);
|
|
etiq_ctx.fillText(prenom[i], 7, 25);
|
|
if (nomjf[i].length > 1) {
|
|
etiq_ctx.fillText("née : " + nomjf[i], 7, 38)
|
|
}
|
|
|
|
}
|
|
|
|
gestion_souris();
|
|
}
|
|
|
|
/**
|
|
* mettre en place les évènements de clic sur la photo
|
|
*/
|
|
function gestion_souris() {
|
|
// pour déplacer le titre
|
|
if (titre !== '') {
|
|
canevas_photo.addEventListener("mousedown", function (e) {
|
|
this.addEventListener("mousemove", deplace_etiquette);
|
|
});
|
|
canevas_photo.addEventListener("mouseup", function (e) {
|
|
this.removeEventListener("mousemove", deplace_etiquette);
|
|
});
|
|
}
|
|
// pour déplacer les étiquettes nom,prénom ...
|
|
for (let i = 0; i < nb_pers; i++) {
|
|
can_etiq[i].addEventListener("mousedown", function (e) {
|
|
this.addEventListener("mousemove", deplace_etiquette);
|
|
});
|
|
can_etiq[i].addEventListener("mouseup", function (e) {
|
|
this.removeEventListener("mousemove", deplace_etiquette);
|
|
});
|
|
}
|
|
;
|
|
ima_fond.addEventListener('mousedown', afficher_formulaire); // pour afficher le formulaire de saisie personne
|
|
ima_fond.addEventListener('mousemove', tracer_cercle); // pour afficher cercle personne
|
|
document.getElementById('circle_svg').addEventListener('contextmenu', function (e) {
|
|
e.preventDefault();
|
|
menu_modif(e);
|
|
}, false); // menu modif personne
|
|
};
|
|
|
|
function deplace_etiquette(e) {
|
|
e.target.style.top = e.pageY - 15 + "px";
|
|
e.target.style.left = e.pageX - 30 + "px";
|
|
};
|
|
|
|
function menu_modif() {
|
|
menu.style.left = cercle.offsetLeft + 10 + "px";
|
|
menu.style.top = cercle.offsetTop + 40 + "px";
|
|
menu.style.visibility = "visible";
|
|
}
|
|
|
|
function supprimer_personne() {
|
|
misajour_xml();
|
|
x = data_xml.getElementsByTagName("personne")[ibac];
|
|
x.parentNode.removeChild(x);
|
|
for (let i = 0; i < nb_pers; i++) {
|
|
x = can_etiq[i];
|
|
x.parentNode.removeChild(x);
|
|
}
|
|
cercle.style.visibility = "hidden";
|
|
lecture_xml();
|
|
}
|
|
|
|
function creation_data_xml() {
|
|
let x, i;
|
|
let txt = "";
|
|
let text = "<photo>" +
|
|
"<titre titx='50px' tity='50px'>Titre " + fond.name + "</titre>" +
|
|
"<date> </date>" +
|
|
"<lieu> </lieu>" +
|
|
"<commentaire> </commentaire>" +
|
|
"</photo>";
|
|
|
|
let parser_face = new DOMParser();
|
|
data_xml = parser_face.parseFromString(text, "text/xml");
|
|
// documentElement always represents the root node
|
|
x = data_xml.documentElement.childNodes;
|
|
for (i = 0; i < x.length; i++) {
|
|
txt += x[i].nodeName + ": " + x[i].childNodes[0].nodeValue + "<br>";
|
|
}
|
|
};
|
|
|
|
function envoi_formulaire_ajout() {
|
|
|
|
ajouter_personne_xml("", souris_x, souris_y, "", "");
|
|
|
|
document.getElementById('circle_svg').setAttribute('class', 'invisible');
|
|
lecture_xml();
|
|
}
|
|
|
|
function ajouter_personne_xml(nom_face, fx, fy, fw, fh) {
|
|
let nomform = nom_face
|
|
let nomjfform = ""
|
|
let prenomform = ""
|
|
let anneeform = ""
|
|
let noteform = ""
|
|
let posxx = fx + fw / 2
|
|
let posyy = fy + fh / 2
|
|
let etxx = fx + 10
|
|
let etyy = fy + fh * 2
|
|
document.getElementById('ajout').className = 'invisible';
|
|
|
|
if (!nom_face) {
|
|
posxx = fx
|
|
posyy = fy
|
|
etxx = fx - 30
|
|
etyy = fy + 80
|
|
nomform = document.getElementById("nom").value
|
|
nomjfform = document.getElementById("nom_jeune_fille").value
|
|
prenomform = document.getElementById("prenom").value
|
|
anneeform = document.getElementById("annee").value
|
|
noteform = document.getElementById("note").value
|
|
}
|
|
// création d'un nouvel élément <personne> dans data_xml
|
|
let personne_ = data_xml.createElement("personne");
|
|
let nom_ = data_xml.createElement("nom");
|
|
nom_.appendChild(data_xml.createTextNode(nomform));
|
|
let nom_jf_ = data_xml.createElement("nom_jeune_fille");
|
|
nom_jf_.appendChild(data_xml.createTextNode(nomjfform));
|
|
let prenom_ = data_xml.createElement("prenom");
|
|
prenom_.appendChild(data_xml.createTextNode(prenomform));
|
|
let annee_ = data_xml.createElement("annee_naiss");
|
|
annee_.appendChild(data_xml.createTextNode(anneeform));
|
|
let note_ = data_xml.createElement("note");
|
|
note_.appendChild(data_xml.createTextNode(noteform));
|
|
let position_ = data_xml.createElement("position");
|
|
position_.setAttribute("posx", posxx);
|
|
position_.setAttribute("posy", posyy);
|
|
position_.setAttribute("etx", etxx);
|
|
position_.setAttribute("ety", etyy);
|
|
personne_.appendChild(nom_);
|
|
personne_.appendChild(nom_jf_);
|
|
personne_.appendChild(prenom_);
|
|
personne_.appendChild(annee_);
|
|
personne_.appendChild(note_);
|
|
personne_.appendChild(position_);
|
|
data_xml.getElementsByTagName("photo")[0].appendChild(personne_)
|
|
};
|
|
|
|
function modifier_personne() {
|
|
mode_saisie = "false";
|
|
afficher_formulaire(this);
|
|
document.getElementById('nom').setAttribute('value', nom[ibac]);
|
|
document.getElementById('nom_jeune_fille').setAttribute('value', nomjf[ibac]);
|
|
document.getElementById('prenom').setAttribute('value', prenom[ibac]);
|
|
document.getElementById('annee').setAttribute('value', annee[ibac]);
|
|
document.getElementById('note').setAttribute('value', note[ibac]);
|
|
document.getElementById('titre').setAttribute('value', titre);
|
|
menu.style.visibility = 'hidden';
|
|
document.getElementById("enreg").style.visibility = "hidden";
|
|
alert("Fonction en cours de développement")
|
|
};
|
|
|
|
function position_souris(canvas, evt) {
|
|
let rect = canvas.getBoundingClientRect();
|
|
return {
|
|
x: evt.screenX - rect.left ,
|
|
y: evt.screenY - rect.top
|
|
};
|
|
};
|
|
|
|
function tracer_cercle(e) {
|
|
// document.getElementsByTagName("svg")[0].setAttribute('height', image.naturalHeight);
|
|
// document.getElementsByTagName("svg")[0].setAttribute('width', image.naturalWidth);
|
|
// let pos_x = position_souris(ima_fond, e).x;
|
|
// let pos_y = position_souris(ima_fond, e).y;
|
|
// for (let i = 0; i < nb_pers; i++) {
|
|
// let dx = posx[i] - pos_x;
|
|
// let dy = posy[i] - pos_y;
|
|
// let dist2 = dx * dx + dy * dy;
|
|
// let rayon2 = rayon * rayon;
|
|
//
|
|
// if (dist2 < rayon2) {
|
|
// ibac = i
|
|
// can_etiq[i].style.background = "palegreen"
|
|
// cercle.setAttribute("cx", posx[i]);
|
|
// cercle.setAttribute("cy", posy[i]);
|
|
// cercle.setAttribute("r", rayon);
|
|
// cercle.style.visibility = "visible";
|
|
// return
|
|
// }
|
|
// }
|
|
// ;
|
|
// cercle.style.visibility = "hidden";
|
|
// if (nb_pers != 0) {
|
|
// can_etiq[ibac].style.backgroundColor = "oldlace";
|
|
// }
|
|
};
|
|
|
|
|
|
/**
|
|
* montre le formulaire là où l'on clique
|
|
* @param e
|
|
*/
|
|
function afficher_formulaire(e) {
|
|
let formulaire_ajout = document.getElementById('ajout')
|
|
let highlight_circle = document.getElementById('circle_svg')
|
|
souris_x = e.clientX ;
|
|
souris_y = e.clientY + document.documentElement.scrollTop;
|
|
if (souris_y - document.getElementById('ajout').height < 0) {
|
|
sourisy = 50
|
|
}
|
|
formulaire_ajout.style.left = souris_x + 20 + "px";
|
|
formulaire_ajout.style.top = souris_y + 40 + "px";
|
|
formulaire_ajout.className = 'visible';
|
|
setTimeout(function () {
|
|
document.getElementById("nom").focus();
|
|
}, 10);
|
|
|
|
highlight_circle.style.left = souris_x - circle_svg.offsetWidth /2 + 'px';
|
|
highlight_circle.style.top = souris_y - circle_svg.offsetHeight/2 + 'px';
|
|
highlight_circle.setAttribute('class', 'visible animate__pulse');
|
|
if (mode_saisie) {
|
|
vider_formulaire();
|
|
}
|
|
mode_saisie = "true";
|
|
};
|
|
|
|
function vider_formulaire() {
|
|
document.getElementById('nom').setAttribute('value', "");
|
|
document.getElementById('nom').focus();
|
|
document.getElementById('nom_jeune_fille').setAttribute('value', "");
|
|
document.getElementById('prenom').setAttribute('value', "");
|
|
document.getElementById('annee').setAttribute('value', "");
|
|
document.getElementById('note').setAttribute('value', "");
|
|
|
|
}
|
|
|
|
function misajour_xml() {
|
|
|
|
document.getElementById('circle_svg').setAttribute('class', 'invisible');
|
|
tit.setAttribute("titx", canevas_photo.style.left);
|
|
tit.setAttribute("tity", canevas_photo.style.top);
|
|
for (let i = 0; i < nb_pers; i++) {
|
|
position = data_xml.getElementsByTagName("position")[i];
|
|
position.setAttribute("etx", can_etiq[i].style.left);
|
|
position.setAttribute("ety", can_etiq[i].style.top);
|
|
}
|
|
;
|
|
lecture_xml();
|
|
};
|
|
|
|
|
|
function enregistrer_fichier(fichier) {
|
|
misajour_xml()
|
|
let texte_xml = (new XMLSerializer()).serializeToString(data_xml)
|
|
texte_xml = formatXml(texte_xml)
|
|
let blob = new Blob([texte_xml], {type: "text/plain;charset=utf-8"});
|
|
if (navigator.msSaveBlob) {
|
|
navigator.msSaveBlob(blob, fichier);
|
|
} else {
|
|
let a = document.createElement('a');
|
|
if (a.download === '') ;
|
|
a.setAttribute('download', fichier);
|
|
a.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(texte_xml));
|
|
a.style.display = 'none';
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
}
|
|
}
|
|
|
|
function formatXml(xml, tab) { // tab = optional indent value, default is tab (\t)
|
|
let formatted = '', indent = '';
|
|
tab = tab || '\t';
|
|
xml.split(/>\s*</).forEach(function (node) {
|
|
if (node.match(/^\/\w/)) indent = indent.substring(tab.length); // decrease indent by one 'tab'
|
|
formatted += indent + '<' + node + '>\r\n';
|
|
if (node.match(/^<?\w[^>]*[^\/]$/)) indent += tab; // increase indent
|
|
});
|
|
return formatted.substring(1, formatted.length - 3);
|
|
}
|
|
|
|
function image_finale() {
|
|
misajour_xml()
|
|
let decalx = 5 + image.offsetLeft;
|
|
let decaly = 29 + image.offsetTop;
|
|
let can_imf = document.createElement("canvas");
|
|
document.body.appendChild(can_imf);
|
|
imf_ctx = can_imf.getContext("2d");
|
|
can_imf.width = ima_fond.width;
|
|
can_imf.height = ima_fond.height;
|
|
imf_ctx.drawImage(ima_fond, 0, 0)
|
|
if (titre !== '') {
|
|
let taille = titre.length;
|
|
hauteur = 25
|
|
roundedRect(imf_ctx, tx - decalx, ty - decaly, taille * 11, hauteur, 5, 'lightyellow', 'yellow');
|
|
imf_ctx.drawImage(canevas_photo, tx - decalx, ty - decaly)
|
|
}
|
|
|
|
for (let i = 0; i < nb_pers; i++) {
|
|
let taille = Math.max(nom[i].length, prenom[i].length, nomjf[i].length + 5);
|
|
hauteur = 30
|
|
if (nomjf[i].replace(/\t/g, '').length > 1) {
|
|
hauteur = 45
|
|
}
|
|
roundedRect(imf_ctx, etx[i] - decalx, ety[i] - decaly, taille * 7 + 10, hauteur, 15, 'oldlace', 'blue');
|
|
imf_ctx.drawImage(can_etiq[i], etx[i] - decalx, ety[i] - decaly)
|
|
}
|
|
let a = document.createElement('a');
|
|
if (a.download === '') ;
|
|
a.setAttribute('download', enreg_noms);
|
|
a.setAttribute('href', can_imf.toDataURL("image/png").replace("image/png", "image/octet-stream"));
|
|
a.style.display = 'none';
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
document.body.removeChild(can_imf);
|
|
|
|
function roundedRect(ctx, x, y, width, height, radius, couleur_fond, couleur_trait) {
|
|
ctx.beginPath();
|
|
ctx.strokeStyle = couleur_trait;
|
|
ctx.moveTo(x, y + radius);
|
|
ctx.lineTo(x, y + height - radius);
|
|
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
|
|
ctx.lineTo(x + width - radius, y + height);
|
|
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
|
|
ctx.lineTo(x + width, y + radius);
|
|
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
|
|
ctx.lineTo(x + radius, y);
|
|
ctx.quadraticCurveTo(x, y, x, y + radius);
|
|
ctx.closePath();
|
|
ctx.fillStyle = couleur_fond;
|
|
ctx.fill();
|
|
ctx.stroke();
|
|
}
|
|
}
|