diff --git a/static/js/paints.js b/static/js/paints.js index b48e9f3f271c86df570a7473ee04793d339588fa..a445517ed9465bba83812280b7391ed8350f7575 100644 --- a/static/js/paints.js +++ b/static/js/paints.js @@ -3,7 +3,6 @@ window.onload = function () { exploreInit(); dataHandler.init(); imageHandler.init(); - // pageInit(); changePath(); } @@ -68,21 +67,17 @@ function visuInit() { } const imageHandler = { + currImg: "", imgPos: getImagePos(), viewer: Array(), options: { id: "fabricjsOverlay", selection: false, // NE MARCHE PAS - // scale: 990, - scale: 1000, // to detail hovering zone perPixelTargetFind: true, targetFindTolerance: 0 }, - scaleOption: Object(), overlays: [], - polygonsAreas: [], - polygons: {}, initSide: function (side) { imageHandler.viewer[side] = new OpenSeadragon.Viewer({ id: `openseadragon-${side}`, @@ -112,18 +107,18 @@ const imageHandler = { imageHandler.display(side, document.querySelectorAll('.img-thumbnail')[0].id); } + imageHandler.currImg = url; + // initialisation de l'overlay pour y afficher les zonages setTimeout(() => { this.options.scale = dataHandler.scales[url]; this.overlays[side] = this.viewer[side].fabricjsOverlay(this.options); - displayFigures(side, url); }, "800"); - + }, init: function () { this.initSide("left"); this.initSide("right"); - side="left" const thumbnails = document.querySelectorAll('.img-thumbnail'); [].forEach.call(thumbnails, function (element) { @@ -139,11 +134,6 @@ const imageHandler = { } }; - let toggleBtns = document.querySelectorAll('.toggle-mark'); - [].forEach.call(toggleBtns, function (toggleBtn) { - toggleBtn.addEventListener("click", imageHandler.toggleMark); - }); - let descriptionsZones = document.querySelectorAll(".description-zone"); for (let i = 0; i < descriptionsZones.length; i++) { descriptionsZones[i].addEventListener( @@ -151,85 +141,58 @@ const imageHandler = { function (event) { let pos = getImagePos(); + let currentImage = imageHandler.currImg; - // version dessine les zones en les additionnant - if (document.querySelector(".img-thumbnail.current").classList.contains("zonesRemoved")) { + // version affiche/cache les zones (en les additionnant) au clic dans le texte + if (!document.querySelector(".img-thumbnail.current").classList.contains("zonesActivated")) { // afficher les zones - item = 1; - let x = 0; - let toRemove = [] + let polyIdToChange = 1; let removing = false let textTag = event.target.parentElement.parentElement; - // récupère les id des grand-parents pour savoir quelles zones afficher + + // récupère les id des grand-parents pour savoir quelles zones afficher/masquer for (let a = 0; a < textTag.classList.length; a++) { zoneId = textTag.classList[a]; - for (let z = 0; z < imageHandler.polygonsAreas.length; z++) { - const polyId = imageHandler.polygonsAreas[z].id; - x= z + for (let z = 0; z < dataHandler.polygonsAreas[currentImage].length; z++) { + const polyId = dataHandler.polygonsAreas[currentImage][z].id; if (zoneId == polyId) { - item = polyId; + polyIdToChange = polyId; break; } } - let poly = imageHandler.polygons[item]; - console.group("remove or not") - - // si déjà marqué et qu'on veut enlever : ne fonctionne pas ! ALMOST WORKING - TO CLEAR (TODO) - // ne marche pas si on clique une nouvelle fois + texte ne se décolore pas + + // si déjà affiché et qu'on veut masquer if (imageHandler.overlays[pos].fabricCanvas()._objects.length > 0) { let drawnPolys = imageHandler.overlays[pos].fabricCanvas()._objects; - console.log(imageHandler.overlays[pos].fabricCanvas().getObjects()) - + drawnPolys.forEach(drawnPoly => { - if (drawnPoly.id == item) { - console.log(textTag.classList) - // textTag.classList.remove("corresp"); + if (drawnPoly.id == polyIdToChange) { removing = true; - console.log("---------") - console.log("id :"+drawnPoly.id) - console.log("x : "+x) - console.log("indexOf poly : "+imageHandler.overlays[pos].fabricCanvas()._objects.indexOf(drawnPoly)) - console.log("---------") - x = imageHandler.overlays[pos].fabricCanvas()._objects.indexOf(drawnPoly); - let obj = imageHandler.overlays[pos].fabricCanvas().item(x); - toRemove.push(obj); - imageHandler.overlays[pos].fabricCanvas().remove(obj); - imageHandler.overlays[pos].fabricCanvas().renderAll(); - console.log(imageHandler.overlays[pos].fabricCanvas()._objects) + let polyIndex = imageHandler.overlays[pos].fabricCanvas()._objects.indexOf(drawnPoly); + let polyToRemove = imageHandler.overlays[pos].fabricCanvas().item(polyIndex); - // imageHandler.overlays[pos].fabricCanvas().on('object:removed',function(object){ - // console.warn(object); - // }); + imageHandler.overlays[pos].fabricCanvas().remove(polyToRemove); + imageHandler.overlays[pos].fabricCanvas().renderAll(); } }); - + } - // if(removing){ - // if(textTag.classList.contains("corresp")){ - // textTag.classList.remove("corresp"); - // } - // } - // else{ - if(! removing){ + // si on veut afficher + if (!removing) { // dessine les zones - console.log("here") - imageHandler.overlays[pos].fabricCanvas().add(poly); + let polyToAdd = new fabric.Polygon(dataHandler.polygons[currentImage][polyIdToChange].points, dataHandler.polygons[currentImage][polyIdToChange].infos); + + imageHandler.overlays[pos].fabricCanvas().add(polyToAdd); + let nbPoly = imageHandler.overlays[pos].fabricCanvas()._objects.length - 1; imageHandler.overlays[pos].fabricCanvas().item(nbPoly).set('fill', 'transparent'); imageHandler.overlays[pos].fabricCanvas().item(nbPoly).set('dirty', 'true') imageHandler.overlays[pos].fabricCanvas().requestRenderAll(); imageHandler.overlays[pos].fabricCanvas().item(nbPoly).set('dirty', 'false') - - // textTag.classList.add("corresp"); } - console.groupEnd(); } - toRemove.forEach(element => { - imageHandler.overlays[pos].fabricCanvas().remove(element); - imageHandler.overlays[pos].fabricCanvas().renderAll(); - - }); + removing ? textTag.classList.remove("corresp") : textTag.classList.add("corresp"); } // version colorie les zones sans les additionner @@ -244,8 +207,8 @@ const imageHandler = { // récupère les id des grand-parents pour savoir quelles zones masquer for (let a = 0; a < corresps[y].classList.length; a++) { zoneId = corresps[y].classList[a]; - for (let z = 0; z < imageHandler.polygonsAreas.length; z++) { - const polyId = imageHandler.polygonsAreas[z].id; + for (let z = 0; z < dataHandler.polygonsAreas[currentImage].length; z++) { + const polyId = dataHandler.polygonsAreas[currentImage][z].id; let polyNumber = z; if (zoneId == polyId) { item = polyNumber; @@ -262,10 +225,11 @@ const imageHandler = { // afficher les zones item = 1; // récupère les id des grand-parents pour savoir quelles zones afficher - for (let a = 0; a < event.target.parentElement.parentElement.classList.length; a++) { - zoneId = event.target.parentElement.parentElement.classList[a]; - for (let z = 0; z < imageHandler.polygonsAreas.length; z++) { - const polyId = imageHandler.polygonsAreas[z].id; + parentClasses = event.target.parentElement.parentElement.classList; + for (let a = 0; a < parentClasses.length; a++) { + zoneId = parentClasses[a]; + for (let z = 0; z < dataHandler.polygonsAreas[currentImage].length; z++) { + const polyId = dataHandler.polygonsAreas[currentImage][z].id; let polyNumber = z; if (zoneId == polyId) { item = polyNumber; @@ -273,13 +237,12 @@ const imageHandler = { } } imageHandler.overlays[pos].fabricCanvas().item(item).set('fill', '#DEC9BF'); - imageHandler.overlays[pos].fabricCanvas().item(item).set('opacity', '0.5'); imageHandler.overlays[pos].fabricCanvas().item(item).set('dirty', 'true') imageHandler.overlays[pos].fabricCanvas().requestRenderAll(); imageHandler.overlays[pos].fabricCanvas().item(item).set('dirty', 'false') } + parentClasses.add("corresp"); } - event.target.parentElement.parentElement.classList.add("corresp"); }, false, @@ -290,14 +253,13 @@ const imageHandler = { drawRemoveZones: function () { let image = document.querySelector(".img-thumbnail.current") let url = image.dataset.img; - let pos = getImagePos(); - if (image.classList.contains("zonesRemoved")) { - image.classList.remove("zonesRemoved") - displayAllFigures(url); + clearAll(); + if (image.classList.contains("zonesActivated")) { + image.classList.remove("zonesActivated") } else { - image.classList.add("zonesRemoved") - imageHandler.overlays[pos].fabricCanvas().clear(); + image.classList.add("zonesActivated") + displayAllFigures(url); } // masquer les descriptions sélectionnées précédement @@ -306,41 +268,37 @@ const imageHandler = { corresp.classList.remove('corresp'); } }, - toggleMark: function (evt) { - let btn = evt.currentTarget; - let pos = btn.dataset.pos; - let type = btn.dataset.type; - document.querySelector('#nav-tabContent-' + pos).classList.toggle('disabled-' + type); - }, change: function (evt) { let previous; let thumbnail = evt.currentTarget; let pos = getImagePos(); - let url = thumbnail.dataset.img; - + if (previous = document.querySelector('.img-thumbnail.current')) { previous.classList.remove('current'); } thumbnail.classList.add('current'); - + activeTabs = document.querySelectorAll(".nav-link.active"); for (let activeTab of activeTabs) { if (activeTab.id.includes("image")) { pos = activeTab.id.split("-")[1]; } } - + + clearAll(); imageHandler.display(pos, thumbnail.id); - displayAllFigures(url); - + + imageHandler.currImg = thumbnail.dataset.img; changePath(); }, display: function (imgPos, imageRef) { let url = document.querySelector("#" + imageRef).dataset.img; - // let imageRef = thumbnail.id.substr(thumbnail.id.lastIndexOf("-") + 1); + if (url) { + imageHandler.options.scale = dataHandler.scales[url]; + imageHandler.overlays[imgPos] = imageHandler.viewer[imgPos].fabricjsOverlay(imageHandler.options); imageHandler.viewer[imgPos].open({ type: 'image', url: url @@ -361,147 +319,73 @@ const imageHandler = { } } -const displayFigures = function (side, url){ - - let currentImage = url; - let viewer = imageHandler.viewer[side]; +const displayFigures = function (side, url) { imageHandler.overlays[side].fabricCanvas().clear(); - console.log(currentImage); - - getData().then((data) => { - - let jsonMention = data[0]; - zoom = false; - let i = 0; - - let polygonsPoints = Object(); - imageHandler.polygonsAreas = []; - - // dessine les zones décrites - if (jsonMention.hasOwnProperty(currentImage)) { - - // gestion de l'échelle des zones//images - let scale = jsonMention[currentImage][0] - imageHandler.scaleOption[currentImage] = scale; - - let infosFigure = jsonMention[currentImage][1] - - // get polygons points and their areas - for (let figure in infosFigure) { - i++; - let points = infosFigure[figure]; - - newpoints = [] - for (let index = 0; index < points.length; index++) { - newpoints.push([points[index]["x"], points[index]["y"]]); - } - polygonsPoints[figure] = points; - imageHandler.polygonsAreas.push({ "id": figure, "area": calculateArea(newpoints) }); - } - // sort polygons by area - imageHandler.polygonsAreas.sort(function (a, b) { - return a.area - b.area; - }); - imageHandler.polygonsAreas.reverse(); - - // draw polygons zones in descending orders of areas to avoid overlaps - for (let i = 0; i < imageHandler.polygonsAreas.length; i++) { - - let polyId = imageHandler.polygonsAreas[i].id; - let points = polygonsPoints[polyId]; - - // create poly zone - let poly = new fabric.Polygon(points, { - id: polyId, - // stroke: 'red', - stroke: '#B22222', - strokeWidth: 3, - fill: 'transparent', - // make it impossible to drag or resize zone - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - lockMovementX: true, - lockMovementY: true, - // to detail hovering zone - perPixelTargetFind: true, - // remove selection lines - // hasBorders: false, - hasControls: false, - dirty: false, - hoverCursor: 'pointer' - }); + // draw polygons zones in descending orders of areas to avoid overlaps + for (let i = 0; i < dataHandler.polygonsAreas[url].length; i++) { + let polyId = dataHandler.polygonsAreas[url][i].id; + let poly = new fabric.Polygon(dataHandler.polygons[url][polyId].points, dataHandler.polygons[url][polyId].infos); - // remove draggability indicator - poly.setControlsVisibility({ mtr: false }) + imageHandler.overlays[side].fabricCanvas().add(poly); + } - // add poly zone to list - imageHandler.polygons[polyId] = poly; - // add poly zone to canva - imageHandler.overlays[side].fabricCanvas().add(poly); - } + // highlight clicked zone description + imageHandler.overlays[side].fabricCanvas().on('mouse:up', function (e) { + let previousRefs = document.querySelectorAll(".corresp"); + for (var previousRef of previousRefs) { + previousRef.classList.remove('corresp'); } - - // highlight clicked zone description - imageHandler.overlays[side].fabricCanvas().on('mouse:up', function (e) { - - let previousRefs = document.querySelectorAll(".corresp"); - for (var previousRef of previousRefs) { - previousRef.classList.remove('corresp'); - } - if (e.target) { - console.log(e.target["id"]) - let refs = document.querySelectorAll("." + e.target["id"]); - for (var ref of refs) { - if (!ref.classList.contains("corresp")) { - ref.classList.add('corresp'); - ref.scrollIntoView({ block: "center" }); - } + if (e.target) { + let refs = document.querySelectorAll("." + e.target["id"]); + for (var ref of refs) { + if (!ref.classList.contains("corresp")) { + ref.classList.add('corresp'); + ref.scrollIntoView({ block: "center" }); } } - }); + } + }); - // color overflown zones - imageHandler.overlays[side].fabricCanvas().on('mouse:over', function (e) { - if (e.target) { - // e.target.set('fill', 'pink') - e.target.set('fill', '#DEC9BF') - e.target.set('opacity', '0.5') - // redraw only dirty zones - e.target.set('dirty', 'true') - imageHandler.overlays[side].fabricCanvas().requestRenderAll(); - e.target.set('dirty', 'false') - - // display zones notes - document.querySelector("#zones-infos").innerText = document.querySelector("#" + e.target["id"] + "-note").innerText; - document.querySelector("#zones-infos").style.display = "block"; - } - }); + // color overflown zones + imageHandler.overlays[side].fabricCanvas().on('mouse:over', function (e) { + if (e.target) { + e.target.set('fill', '#DEC9BF') + e.target.set('opacity', '0.5') + // redraw only dirty zones + e.target.set('dirty', 'true') + imageHandler.overlays[side].fabricCanvas().requestRenderAll(); + e.target.set('dirty', 'false') + + // display zones notes + document.querySelector("#zones-infos").innerText = document.querySelector("#" + e.target["id"] + "-note").innerText; + document.querySelector("#zones-infos").style.display = "block"; + } + }); - // uncolor preceding overflown zones - imageHandler.overlays[side].fabricCanvas().on('mouse:out', function (e) { - if (e.target) { - e.target.set('fill', 'transparent') - // redraw only dirty zones - e.target.set('dirty', 'true') - imageHandler.overlays[side].fabricCanvas().requestRenderAll(); - e.target.set('dirty', 'false') - - // display zones notes - document.querySelector("#zones-infos").innerText = ""; - document.querySelector("#zones-infos").style.display = "none"; - } - }); + // uncolor preceding overflown zones + imageHandler.overlays[side].fabricCanvas().on('mouse:out', function (e) { + if (e.target) { + e.target.set('fill', 'transparent') + // redraw only dirty zones + e.target.set('dirty', 'true') + imageHandler.overlays[side].fabricCanvas().requestRenderAll(); + e.target.set('dirty', 'false') + + // display zones notes + document.querySelector("#zones-infos").innerText = ""; + document.querySelector("#zones-infos").style.display = "none"; + } }); } // display described zones on images const displayAllFigures = function (url) { - imageHandler.overlays["left"]._scale = dataHandler.scales[url]; - imageHandler.overlays["right"]._scale = dataHandler.scales[url]; - displayFigures("left", url); - displayFigures("right", url); + clearAll(); + imageHandler.overlays["left"]._scale = dataHandler.scales[url]; + imageHandler.overlays["right"]._scale = dataHandler.scales[url]; + displayFigures("left", url); + displayFigures("right", url); } @@ -571,14 +455,19 @@ function getImagePos() { return pos; } +function clearAll() { + imageHandler.overlays["left"].fabricCanvas().clear(); + imageHandler.overlays["right"].fabricCanvas().clear(); +} + //display note near cursor window.onmousemove = function (e) { - if(document.querySelector("#zones-infos").style.display == "block"){ + if (document.querySelector("#zones-infos").style.display == "block") { let mouseX = e.clientX; let mouseY = e.clientY; let noteX = document.querySelector("#zones-infos").getBoundingClientRect().width; let noteY = document.querySelector("#zones-infos").getBoundingClientRect().height; - + document.querySelector("#zones-infos").style.top = (mouseY - noteY) + 'px'; document.querySelector("#zones-infos").style.left = (mouseX - noteX) + 'px'; } @@ -586,80 +475,74 @@ window.onmousemove = function (e) { const dataHandler = { scales: Object(), - init : function(){ + polygons: Object(), + polygonsAreas: Array(), + init: function () { getData().then((data) => { - console.log("here") - let jsonMention = data[0]; - zoom = false; - let i = 0; - + let polygonsPoints = Object(); - imageHandler.polygonsAreas = []; - + dataHandler.polygonsAreas = []; + for (let currentImage in jsonMention) { - - // gestion de l'échelle des zones//images - let scale = jsonMention[currentImage][0] - dataHandler.scales[currentImage] = scale; - // console.log(dataHandler.scales) - // console.log(dataHandler.scales.hasOwnProperty("https://gallica.bnf.fr/iiif/ark:/12148/btv1b105206468/f103/full/1600,/0/color.jpg")) - - let infosFigure = jsonMention[currentImage][1] - - // get polygons points and their areas - for (let figure in infosFigure) { - i++; - let points = infosFigure[figure]; - - let newpoints = [] - for (let index = 0; index < points.length; index++) { - newpoints.push([points[index]["x"], points[index]["y"]]); - } - polygonsPoints[figure] = points; - imageHandler.polygonsAreas.push({ "id": figure, "area": calculateArea(newpoints) }); + + dataHandler.polygons[currentImage] = {} + dataHandler.polygonsAreas[currentImage] = [] + + // gestion de l'échelle des zones//images + let scale = jsonMention[currentImage][0] + dataHandler.scales[currentImage] = scale; + + let infosFigure = jsonMention[currentImage][1] + + // get polygons points and their areas + for (let figure in infosFigure) { + let points = infosFigure[figure]; + + let newpoints = []; + for (let index = 0; index < points.length; index++) { + newpoints.push([points[index]["x"], points[index]["y"]]); } - - // sort polygons by area - imageHandler.polygonsAreas.sort(function (a, b) { - return a.area - b.area; - }); - imageHandler.polygonsAreas.reverse(); - - // draw polygons zones in descending orders of areas to avoid overlaps - for (let i = 0; i < imageHandler.polygonsAreas.length; i++) { - - let polyId = imageHandler.polygonsAreas[i].id; - let points = polygonsPoints[polyId]; - - // create poly zone - let poly = new fabric.Polygon(points, { - id: polyId, - // stroke: 'red', - stroke: '#B22222', - strokeWidth: 3, - fill: 'transparent', - // make it impossible to drag or resize zone - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - lockMovementX: true, - lockMovementY: true, - // to detail hovering zone - perPixelTargetFind: true, - // remove selection lines - // hasBorders: false, - hasControls: false, - dirty: false, - hoverCursor: 'pointer' - }); - + polygonsPoints[figure] = points; + dataHandler.polygonsAreas[currentImage].push({ "id": figure, "area": calculateArea(newpoints) }); + } + + // sort polygons by area + dataHandler.polygonsAreas[currentImage].sort(function (a, b) { + return a.area - b.area; + }); + dataHandler.polygonsAreas[currentImage].reverse(); + + // draw polygons zones in descending orders of areas to avoid overlaps + for (let i = 0; i < dataHandler.polygonsAreas[currentImage].length; i++) { + + let polyId = dataHandler.polygonsAreas[currentImage][i].id; + dataHandler.polygons[currentImage][polyId] = { "points" : [], "infos" : {}}; + + // add poly infos to create zone + dataHandler.polygons[currentImage][polyId]["points"] = polygonsPoints[polyId]; + dataHandler.polygons[currentImage][polyId]["infos"] = { + id: polyId, + stroke: '#B22222', + strokeWidth: 3, + fill: 'transparent', + // make it impossible to drag or resize zone + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + lockMovementX: true, + lockMovementY: true, + // to detail hovering zone + perPixelTargetFind: true, + // remove selection lines + hasBorders: false, + hasControls: false, // remove draggability indicator - poly.setControlsVisibility({ mtr: false }) - - // add poly zone to list - imageHandler.polygons[polyId] = poly; - } + setControlsVisibility: ({ mtr: false }), + dirty: false, + hoverCursor: 'pointer' + }; + } } }) } diff --git a/templates/navbar_menu.html.j2 b/templates/navbar_menu.html.j2 index 779dc2265b44fa4f7fbfa057c0702bec504ec7c2..cecdc495faaa470bac0a6083c6acf6a5afe16cd3 100644 --- a/templates/navbar_menu.html.j2 +++ b/templates/navbar_menu.html.j2 @@ -103,6 +103,19 @@ <a class="btn btn-menu me-3" href="{{ url_for('vue', vueName='manuscripts') }}"><i class="fa-solid fa-scroll"></i> Manuscrits</a> </li>--> + <li class="nav-item dropdown"> + <a class="dropdown-toggle btn btn-menu me-3" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false"> + <i class="fa-solid fa-palette"></i> Peintures</a> + <ul class="dropdown-menu dropdown-paints" aria-labelledby="navbarDropdown"> + <li> + <a class="dropdown-item btn-summary" href="{{ url_for('facsimile', paintsPage='paints1') }}"></i>Peintures du Livre I</a> + </li> + <li> + <a class="dropdown-item btn-summary" href="{{ url_for('facsimile', paintsPage='paints2') }}"></i>Peintures du Livre II</a> + </li> + </ul> + </li> + <li class="nav-item"> <a class="btn btn-menu me-3" href="{{ url_for('vue', vueName='index_person') }}"><i class="fa-solid fa-bars"></i> Index</a> </li> @@ -130,21 +143,6 @@ <li class="nav-item"> <a class="btn btn-menu me-3" href="{{ url_for('vue', vueName='team') }}"><i class="fa-solid fa-people-group"></i> Équipe</a> </li> - - <!-- - <li class="nav-item dropdown"> - <a class="dropdown-toggle btn btn-menu me-3" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false"> - <i class="fa-solid fa-palette"></i> Peintures</a> - <ul class="dropdown-menu dropdown-paints" aria-labelledby="navbarDropdown"> - <li> - <a class="dropdown-item btn-summary" href="{{ url_for('facsimile', paintsPage='paints1') }}"></i>Peintures du Livre I</a> - </li> - <li> - <a class="dropdown-item btn-summary" href="{{ url_for('facsimile', paintsPage='paints2') }}"></i>Peintures du Livre II</a> - </li> - </ul> - </li> - --> </ul> </div> </div>