IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[Snap.svg] z-index sur éléments SVG


Sujet :

JavaScript

  1. #1
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut [Snap.svg] z-index sur éléments SVG
    Salut, tout est dans le titre...
    Comment gérer la profondeur des dessins sur paper avec snap svg ?
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    maform.attr({
       .......
      'z-index'=1
    }); // ne fonctionne pas

    C'était pour faire de la 3D, la profondeur est indispensable...

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 110
    Points : 44 929
    Points
    44 929
    Par défaut
    Bonjour,
    étourderie !?!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    maform.attr({
       .......
      'z-index': 1
    });
    l'affectation d'une valeur à une propriété, dans un objet, se fait via un :.

  3. #3
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    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...

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 110
    Points : 44 929
    Points
    44 929
    Par défaut
    Mais bon si z-index sous snap svg était opérationnel, ce serait mieux...
    je n'avais pas percuté sur la propriété

    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 ».


    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é...
    C'est effectivement la façon de procéder, on peut utiliser par exemple cette extension pour snapSVG :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
      };
    });
    mais plutôt réserver élément par élément.

    Tu peux également injecter directement un Snap.set().items dans un SVG.group() après ton tri.

  5. #5
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    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 javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 110
    Points : 44 929
    Points
    44 929
    Par défaut
    Mais, ça m'oblige à faire un paper.clear() à chaque frame
    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.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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());

    Et en plus, ça me permettait de faire un paper.g()
    on avait vu dans une précédente discussion que tu gagnai en vitesse donc oui c'est une bonne orientation.


    J'avais déjà remarqué dans la doc raphaël => toFront() toBack() (et non dans snap SVG) sans approfondir.
    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 !

    J'ai fait un exemple de modification de l'ordre des éléments dans un groupe SVG, c'est basé sur Snap.svg :

  7. #7
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    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

  8. #8
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Re, le problème, c'est que tes fonctions ne marchent pas successivement plusieurs fois de suite...
    J'avais trouvé la solution en faisant :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
     for (let j=0; j<( ind2-ind ); j++) bringToBack( tabFace[ind2].innerHTML );
    Mais manque de bol, en faisant successivement plusieurs bringToBack(), la première est opérationnelle mais pas les suivantes.
    ça se remarque sur ta démo.

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     function bringToBack(elt) {
                const parent = elt.node.parentNode;
                 parent.insertBefore(elt.node, parent.firstElementChild);
                 return elt;
    };

  9. #9
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    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 ???

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 110
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 110
    Points : 44 929
    Points
    44 929
    Par défaut
    Re, le problème, c'est que tes fonctions ne marchent pas successivement plusieurs fois de suite...
    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.

    Ce n'est donc visiblement pas cela que tu souhaites réaliser.


    Mais manque de bol, en faisant successivement plusieurs bringToBack()
    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 .


    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.


    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.

    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() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
    }
    je les ai ajouté dans la démo si tu veux faire des tests, exemple de test, à mettre dans la console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tabElements[4].incZindex()
    tabElements[8].decZindex()
    Bien sûr une gestion plus pointue pourrait toujours être envisagée.

  11. #11
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    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.
    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...
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Snap.svg] Evénements touche sur support tactile
    Par Archimède dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 08/03/2022, 18h34
  2. [Snap.svg] Fixer des limites sur un drag and drop
    Par Archimède dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 06/02/2022, 10h27
  3. [Snap.svg] Optimisation animation
    Par Archimède dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 17/03/2021, 18h29
  4. Fabric.js VS Snap SVG
    Par arnaud_verlaine dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 27/08/2020, 14h15
  5. z-index sur élément suivant dans une liste
    Par Xunil dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 28/05/2009, 22h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo