--- layout: layouts/page.njk title: Atelier --- Optimisation des fichiers SVG ``` svgo machine-1.svg -o machine-1-o.svg ``` Si vous n'arrivez pas à utiliser la commande svg vous pouvez utiliser le module Visual Studio Code `svgo` Du fait de la projection isométrique le viewbox de l'illustration doit être plus grand que la grille. ```svg ``` Le motif. Seuls les côté haut et droit sont dessinés les autres sont commun au motif suivant. ```svg ``` La grille et un rectangle de sélection rouge. La grille fait 400 x 400 le rectangle 25 x 25 ```svg ``` La projection isométrique ```svg ``` Le groupe qui va contenir les machines ```svg ``` ### le sélecteur les différentes valeurs des machines sont stockées dans des champs data des éléments html. ```html ``` ### Le javascript Récupérer les coordonnées de l'illustration svg et en déduire le facteur de zoom avec le viewbox. Définir l'angle de projection isométrique = 30° Récupérer le rectangle de sélection rouge ```javascript let coord = document.getElementsByTagName("svg")[0].getBoundingClientRect(); const zoom = Math.min(750.0 / coord.width, 420.0 / coord.height); const angle = - Math.PI / 6; const rect = document.getElementById("rect"); ``` Lorsque la souris bouge au dessus de la grille, lire les coordonnées `offsetX` et `offsetY` et les convertir dans la projection isométrique. Fixer les coordonnées x,y du rectangle rouge avec les coordonnées calculées, en prenant soin de faire un modulo du pas de 25 et d'inclure la marge de 5px du bord de l'écran. ```javascript document.getElementById("grille").addEventListener("mousemove", function (evt) { let {x, y} = planToIsometric(evt.offsetX, evt.offsetY) rect.setAttribute("x", Math.floor(x * zoom / 25) * 25 + 5); rect.setAttribute("y", Math.floor(y * zoom / 25) * 25 + 5); }); ``` Au clic sur la grille lire la valeur du sélecteur ```javascript document.getElementById("grille").addEventListener("click", async function (evt) { const m = document.getElementsByTagName("select")[0].value; ``` Récupérer le fichier svg optimisé de la machine correspondante ```javascript const data = await fetch(`machine-${m}-o.svg`) const str = await data.text(); ``` Convertir le texte reçu au format xml et extraire l'élément svg. ```javascript const xml = new window.DOMParser().parseFromString(str, "image/svg+xml"); const svg = xml.children[0]; ``` Récupérer les différentes données de la machine ```javascript const option = document.querySelector(`option[value='${m}']`) let scale = option.dataset["scale"]; let width = option.dataset["width"]; let height = option.dataset["height"]; let originx = option.dataset["originx"]; let originy = option.dataset["originy"]; ``` Ajuster la taille du svg en fonction des données ```javascript svg.setAttribute("width", width * scale); svg.setAttribute("height", height * scale); ``` Convertir les coordonnées de la souris sur la grille en coordonnées isométriques. Ajuster ces coordonnées au pas de la grille de 25 px en tenant compte de la marge de 5px avec le bord de l'écran. ```javascript let {x, y} = planToIsometric(evt.clientX , evt.clientY); x = Math.ceil(x * zoom / 25) * 25 + 5; y = Math.ceil(y * zoom / 25) * 25 + 5; ``` Retourner les coordonnées isométrique en coordonnées réelles, car les illustrations des machines sont déja en 3D et ne doivent pas donc subir de nouvelle transformation ```javascript ({x, y} = isometricToPlan(x , y)); ``` Placer l'illustration de la machine aux coordonnées trouvées en se décalant à l'origine (coin inférieur droit) de la machine et ajuster au facteur d'échelle. ```javascript svg.setAttribute("x", x - originx * scale); svg.setAttribute("y", y - originy * scale); document.getElementById("atelier").appendChild(svg); ``` Fonction complète : ```javascript document.getElementById("grille").addEventListener("click", async function (evt) { const m = document.getElementsByTagName("select")[0].value; const data = await fetch(`machine-${m}-o.svg`) const str = await data.text(); const xml = new window.DOMParser().parseFromString(str, "image/svg+xml"); const svg = xml.children[0]; const option = document.querySelector(`option[value='${m}']`) let scale = option.dataset["scale"]; let width = option.dataset["width"]; let height = option.dataset["height"]; let originx = option.dataset["originx"]; let originy = option.dataset["originy"]; svg.setAttribute("width", width * scale); svg.setAttribute("height", height * scale); let {x, y} = planToIsometric(evt.clientX , evt.clientY); x = Math.ceil(x * zoom / 25) * 25 + 5; y = Math.ceil(y * zoom / 25) * 25 + 5; ({x, y} = isometricToPlan(x , y)); svg.setAttribute("x", x - originx * scale); svg.setAttribute("y", y - originy * scale); document.getElementById("atelier").appendChild(svg); }); ``` télécharger le fichier html