Salut, tout est dans le titre...
Comment gérer la profondeur des dessins sur paper avec snap svg ?
Code:
1
2
3
4
5 maform.attr({ ....... 'z-index'=1 }); // ne fonctionne pas
C'était pour faire de la 3D, la profondeur est indispensable...
Version imprimable
Salut, tout est dans le titre...
Comment gérer la profondeur des dessins sur paper avec snap svg ?
Code:
1
2
3
4
5 maform.attr({ ....... 'z-index'=1 }); // ne fonctionne pas
C'était pour faire de la 3D, la profondeur est indispensable...
Bonjour,
étourderie !?!
l'affectation d'une valeur à une propriété, dans un objet, se fait via un :.Code:
1
2
3
4 maform.attr({ ....... 'z-index': 1 });
Salut, oui en effet mais j'avais bien mis un ':' dans mon attr... sur mon code (je n'ai pas fait attention dans le post hier soir) et ça ne fonctionne pas. En fait, j'ai l'impression que le z-index n'existe pas avec SVG ou alors je suis passé à côté. Ceci dit, les layers apparaissent dans l'ordre de progression dans le code et comme je refais un cube 3D dont les faces sont dans un tableau, il suffit de faire un tri de ce tableau en fonction de la profondeur z du centre de chaque face dont je connais la valeur et le problème sera réglé...
Mais bon si z-index sous snap svg était opérationnel, ce serait mieux...
je n'avais pas percuté sur la propriété :oops:Citation:
Mais bon si z-index sous snap svg était opérationnel, ce serait mieux...
Ce n'est pas seulement « snapSVG » qui ne la supporte pas mais les éléments SVG, les autres bibliothèque, à ma connaissance, ne le gèrent pas non plus.
La méthode de rendu des éléments est décrite dans la spécification : Scalable Vector Graphics (SVG) 2, en gros les premiers arrivés sont dessous, on empile mais pas de z-index pour modifier l'« ordre ».
C'est effectivement la façon de procéder, on peut utiliser par exemple cette extension pour snapSVG :Citation:
il suffit de faire un tri de ce tableau en fonction de la profondeur z du centre de chaque face dont je connais la valeur et le problème sera réglé...
mais plutôt réserver élément par élément.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 Snap.plugin(function(Snap, Element, Paper, global) { const elProto = Element.prototype; elProto.bringToFront = function() { const parent = this.node.parentNode; parent.appendChild(this.node); return this; }; elProto.bringToBack = function() { const parent = this.node.parentNode; parent.insertBefore(this.node, parent.firstElementChild); return this; }; });
Tu peux également injecter directement un Snap.set().items dans un SVG.group() après ton tri.
Salut, en fait après de multiples recherches, j'avais vu que la propriété n'était pas prise en charge en SVG... Apparemment, c'est en projet pour la prochaine version de SVG2 d'après ce que j'ai compris...
Alors, je fais tourner un cube 3D en rotation sur les trois dimensions et donc pour la priorité des faces, je m'en suis sorti comme ça :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 for (let i=0 ; i<=5;i++){ Face[i].position(); //position des points 3D définissant ma face (parmi les 6) zvalues[i]=Face[i].zvalue();//tableau de la profondeur du centre des faces } triorders=zvalues.sort(tri);//tri des profondeurs par ordre croissant (avec tri : const tri=(a,b)=>a-b; ) triorders.forEach( (item,ind) => { //on balaye les valeurs de profondeurs par ordre croissant Face.forEach( (item2,ind2)=>{ // on balaye les faces if (item2.zvalue()===item) { // si la profondeur de la face est égale à la valeur profondeur Face[ind2].Tracer(3,tabcol[ind2]);//on dessine dans le bon ordre la face: paper.polygon(....) } }); });
Mais, ça m'oblige à faire un paper.clear() à chaque frame au lieu de redéfinir l'attribut des coordonnées de mes point dans polygone() pour mes faces qui sont redessinées (donc redéfinies) dans le bon ordre... Avec z-index, je crée mes faces une fois pour toute et je me débrouille avec attr() pour changer mes coords de points et la profondeur... C'était plus cool.
Et en plus, ça me permettait de faire un paper.g() avec mes faces une fois pour toute et de lui associer une class darken pour faire du soustractif en fonction de la lumière que je vais projeter sur le cube en rotation..
En faisant un paper.g() à chaque fois et en ajoutant ma class 'darken', ça plombe l'animation ...
Je regarde bringToFront() etc.. J'avais déjà remarqué dans la doc raphaël => toFront() toBack() (et non dans snap SVG) sans approfondir. C'est une excellente idée...Il doit y avoir moyen de s'en sortir...
Merci pour tes lumières !
non tu n'es pas obligé, dès que les éléments sont dans ton SVG il te suffit de les réordonner dans l'arbre de rendu et des les réinjecter dans le paper, tout du moins sous Snap.svg.Citation:
Mais, ça m'oblige à faire un paper.clear() à chaque frame
Code:
1
2
3
4
5
6
7
8 // récup. élément SVG const oSVG = Snap("#zoneSVG"); // création d'un groupe const paperGroup = oSVG.group({id: "group-element"}); // affichage dans l'ordre où tabElements et un array d'éléments SVG paperGroup.add(tabElements); // inversion de l'ordre sans rien faire de plus paperGroup.add(tabElements.reverse());
on avait vu dans une précédente discussion que tu gagnai en vitesse donc oui c'est une bonne orientation.Citation:
Et en plus, ça me permettait de faire un paper.g()
la difficulté est en fait de faire abstraction d'une pour utiliser l'autre en, si possible, ne gardant que le meilleur via le Snap.plugin !Citation:
J'avais déjà remarqué dans la doc raphaël => toFront() toBack() (et non dans snap SVG) sans approfondir.
J'ai fait un exemple de modification de l'ordre des éléments dans un groupe SVG, c'est basé sur Snap.svg :
Merci, ça va m'être bien utile et ça complète la doc officielle. Pour l'instant, il faut que je crée mon paper.polygon dans le constructeur de mes faces et dans ma fonction Tracer(), il faut que je fasse modifier l'attribut points de mon paper.polygon pour éviter de faire un paper.clear() dans le callback de mon animation.
Après, c'est là que ton code va m'être bien utile ;)
Je regarde ça lorsque je pourrai.
Bon week-end et encore merci ta démo :ccool:
Re, le problème, c'est que tes fonctions ne marchent pas successivement plusieurs fois de suite...
J'avais trouvé la solution en faisant :
Mais manque de bol, en faisant successivement plusieurs bringToBack(), la première est opérationnelle mais pas les suivantes.Code:for (let j=0; j<( ind2-ind ); j++) bringToBack( tabFace[ind2].innerHTML );
ça se remarque sur ta démo.
Code:
1
2
3
4
5
6 function bringToBack(elt) { const parent = elt.node.parentNode; parent.insertBefore(elt.node, parent.firstElementChild); return elt; };
Salut, en fait c'est normal, le parent reste le même. Il faudrait que l'elt devienne le parent à la fin de la fonction. un appendChild(parent.node), j'ai tenté le coup mais sans succès.
En revanche, j'ai tenté empiriquement un truc absurde, soit un bringToBack suivi d'un bringToFront, normalement rien ne devrait se produire étant donné que je fais la transformation inverse aussitôt. et là, ça marche ???
cela fonctionne bien c'est le principe que tu as mal appréhendé, lorsque tu mets en dessous, tu mets en dessous de tous les éléments et idem pour la mise au dessus.Citation:
Re, le problème, c'est que tes fonctions ne marchent pas successivement plusieurs fois de suite...
Ce n'est donc visiblement pas cela que tu souhaites réaliser.
dans ton exemple, tu fais un bringToBack() sur le même élément donc une fois en dessous il y est point pas la peine d'insister il n'ira pas plus bas ;).Citation:
Mais manque de bol, en faisant successivement plusieurs bringToBack()
J'ai mis à jour la démo en ajoutant deux boutons qui permettent de mieux visualiser le fonctionnement.
Regarde le « tableau » de l'ordre d'affichage qui se met à jour en direct.
Je pense que tu commences à comprendre ce qui se passe, c'est du tout ou rien ou l'élément est en dessous ou il est au dessus mais pas sur une position intermédiaire.Citation:
En revanche, j'ai tenté empiriquement un truc absurde, soit un bringToBack suivi d'un bringToFront, normalement rien ne devrait se produire étant donné que je fais la transformation inverse aussitôt. et là, ça marche ???
Si je comprends ce que tu souhaites, c'est de mettre un élément en dessous ou au dessus mais en décalant d'un seul « cran ».
Pour cela tu pourrais envisager deux fonction comme suit, à ajouter dans la partie Snap.plugin() :
je les ai ajouté dans la démo si tu veux faire des tests, exemple de test, à mettre dans la console :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 // mets en dessous de l'élément qui le précède elProto.decZindex = function() { const domElement = this.node; const prevElement = domElement.previousElementSibling; if (prevElement) { domElement.parentNode.insertBefore(domElement, prevElement); } return this; } // met au dessus de l'élément qui le suit elProto.incZindex = function() { const domElement = this.node; const nextElement = domElement.nextElementSibling; if (nextElement) { domElement.parentNode.insertBefore(domElement, nextElement.nextElementSibling); } return this; }
Bien sûr une gestion plus pointue pourrait toujours être envisagée.Code:
1
2 tabElements[4].incZindex() tabElements[8].decZindex()
En fait, mes faces se réorganisent convenablement avec simplement bringToFront donc mon problème est réglé...Plus besoin de chercher midi à 14 heures...Citation:
En revanche, j'ai tenté empiriquement un truc absurde, soit un bringToBack suivi d'un bringToFront, normalement rien ne devrait se produire étant donné que je fais la transformation inverse aussitôt. et là, ça marche ???
Je pense que tu commences à comprendre ce qui se passe, c'est du tout ou rien ou l'élément est en dessous ou il est au dessus mais pas sur une position intermédiaire.
Le cumule de bringToBack, bringToFront est inutile. Seul bringToFront est pris en compte. Autant pour moi. En fait je remets tout en haut de la pile...
Et, c'est pour ça que ça fonctionne...
Merci