web-dev-qa-db-fra.com

Définition du fichier d'origine de transformation sur le groupe SVG ne fonctionnant pas dans FireFox

Je ne parviens pas à faire fonctionner transform-Origin dans Firefox (v.18 +, autres versions non testées). Les navigateurs Webkit fonctionnent comme prévu.

J'essaie de placer l'origine au centre du groupe, mais rien de ce que j'ai essayé n'a fonctionné jusqu'à présent. 

Voici le code:

<!DOCTYPE html>
<html> 
    <head>
        <title>TEST</title>
        <style>
            #test{
                -webkit-transform-Origin: 50% 50%;
                transform-Origin: center center;

                -webkit-animation: prop 2s infinite;
                animation:         prop 2s infinite;
            }

            @-webkit-keyframes prop {
              0%    { -webkit-transform: scale(1,1);}
              20%   { -webkit-transform: scale(1,.8);}
              40%   { -webkit-transform: scale(1,.6);}
              50%   { -webkit-transform: scale(1,.4);}
              60%   { -webkit-transform: scale(1,.2);}
              70%   { -webkit-transform: scale(1,.4);}
              80%   { -webkit-transform: scale(1,.6);}
              90%   { -webkit-transform: scale(1,.8);}
              100%  { -webkit-transform: scale(1,1);}
            }

            @keyframes prop {
              0%    { transform: matrix(1, 0, 0, 1, 0, 0);}
              20%   { transform: matrix(1, 0, 0, .8, 0, 0);}
              40%   { transform: matrix(1, 0, 0, .6, 0, 0);}
              50%   { transform: matrix(1, 0, 0, .4, 0, 0);}
              60%   { transform: matrix(1, 0, 0, .2, 0, 0);}
              70%   { transform: matrix(1, 0, 0, .4, 0, 0);}
              80%   { transform: matrix(1, 0, 0, .6, 0, 0);}
              90%   { transform: matrix(1, 0, 0, .8, 0, 0);}
              100%  { transform: matrix(1, 0, 0, 1, 0, 0);}
            }
        </style>
    </head>
    <body>
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128px" height="128px" viewBox="0 0 16 16">
            <g id="test">
                <rect fill="#404040" x="7.062" y="3.625" width="1.875" height="8.75"/>
            </g>
        </svg>
    </body>
</html>

Merci de votre aide!

23
kevinstueber

J'essayais de faire pivoter un graphique simple cog svg autour de son point central en utilisant une transition CSS. J'ai eu le même problème que toi avec Firefox; transform-Origin semblait n'avoir aucun effet.

La solution a été de dessiner la forme svg originale de sorte que son centre se situe à la coordonnée 0, 0:

<svg x="0px" y="0px" width="400px" height="400px" viewBox="0 0 400 400">
    <rect id="myObject" x="-50" y="-50" fill="#E52420" width="100" height="100"/>
</svg>

Ajoutez ensuite un groupe autour de lui et traduisez-le à la position souhaitée:

<svg x="0px" y="0px" width="400px" height="400px" viewBox="0 0 400 400">
    <g transform="translate(150, 100)">
        <rect id="myObject" x="-50" y="-50" fill="#E52420" width="100" height="100"/>
    </g>
</svg>

Vous pouvez maintenant appliquer des transitions css qui devraient fonctionner dans Firefox (j'ajoute une classe à la balise HTML à l'aide de JavaScript basé sur une action de l'utilisateur (js-rotateObject) et utilise Minimizr pour vérifier que le navigateur peut gérer les transformations et les transitions (.csstransforms.csstransitions):

#myObject{
    transform: rotate(0deg);
    transition: all 1s linear;
}

.csstransforms.csstransitions.js-rotateObject #myObject{
    transform: rotate(360deg);
}

J'espère que cela pourra aider.

23
Websemantic

Depuis Firefox 55 (publié le 8 août 2017), la propriété CSS "transform-box" est maintenant prise en charge. Si vous définissez cette option sur "Fill-Box", elle imitera celle de Chrome en ce qui concerne la transformation-Origin dans les arbres SVG.

transform-Origin: center; /* or transform-Origin: 50% */
transform-box: fill-box;

Mise à jour 2017-9-14

Vous pouvez sélectionner les éléments dont vous avez besoin dans la structure SVG ou, comme le souligne Tom dans les commentaires, vous pouvez simplement l'appliquer à tous les descendants de l'élément SVG (tant que le style n'interfère pas atteindre):

svg .my-transformed-element {
    transform-Origin: center; /* or transform-Origin: 50% */
    transform-box: fill-box;
}

ou

svg * {
    transform-Origin: center; /* or transform-Origin: 50% */
    transform-box: fill-box;
}
14
Jim

La réponse de @ PatrickGrey a parfaitement fonctionné pour moi, mais je devais gérer un SVG beaucoup plus complexe comportant plusieurs chemins. J'ai réussi à résoudre ce problème en utilisant Inkscape, mais il s'agissait d'un processus en plusieurs étapes. Je vous recommande de faire cela avec Inkscape XML Editor ouvert afin que vous puissiez voir ce qui se passe.

  1. Sélectionnez les éléments à transformer et choisissez Objet> Groupe pour créer un nouveau groupe. Faites glisser ce groupe afin qu'il soit centré sur le coin supérieur gauche du document. Cela applique un attribut transform="translate(…, …)" au groupe.

  2. Choisissez Objet> Dissocier dans le menu. Cela "aplatira" l'attribut de transformation, en appliquant toutes les transformations de coordonnées aux éléments du groupe.

  3. Les éléments d'origine doivent toujours être sélectionnés. Choisissez Objet> Groupe pour les réintégrer dans un groupe. Si vous utilisez CSS pour transformer les éléments, ajoutez votre attribut ID ou class à ce groupe (l'éditeur XML est pratique pour ce bit ou vous pouvez modifier l'ID du groupe en cliquant dessus avec le bouton droit de la souris et en choisissant Propriétés de l'objet Les classes devront être ajoutées via l'éditeur XML ou ultérieurement dans votre éditeur de texte.).

  4. Avec le groupe sélectionné, choisissez Objet> Groupe à nouveau. Cela crée un nouveau groupe autour du groupe d'origine.

  5. Faites glisser ce nouveau groupe à l'emplacement approprié dans le document. Si vous inspectez le DOM à l'aide de l'éditeur XML, vous verrez que transform="translate(…, …)" est ajouté au groupe outer .

  6. Toutes les transformations CSS peuvent maintenant être appliquées au groupe inner , et elles seront traitées de manière cohérente par Chrome et Firefox.

Merci à @ PatrickGrey.co.uk pour la perspicacité initiale. La partie la plus délicate était de déterminer comment appliquer la transformation initiale aux coordonnées de l’objet complexe sans recourir à l’arrachage de cheveux ni à des calculs compliqués. L'astuce "Grouper, déplacer, dissocier" était documentée à quelques endroits sur StackOverflow, mais je l'avais oubliée jusqu'à aujourd'hui. Espérons que ces étapes pourront épargner beaucoup de chagrin à quelqu'un d'autre.

7
thirdender

Selon les commentaires dans ce rapport de bogue , la valeur par défaut de Firefox pour transform-box est différente de celle de Chrome. À partir de Firefox 55, cette propriété peut maintenant être définie sans définir d'indicateur. 

Cela a résolu le problème pour moi:

transform-box: fill-box
transform-Origin: center center
2
LandonSchropp

Si vous pouvez utiliser une valeur de pixel fixe, utilisez-la à la place pour la faire fonctionner.

-moz-transform-Origin: 25px 25px;
-ms-transform-Origin:  25px 25px;
-o-transform-Origin: 25px 25px;
-webkit-transform-Origin:  25px 25px;
transform-Origin: 25px 25px;

Certains navigateurs ne supportent toujours pas transform-Origin avec les valeurs en pourcentage comme ils le devraient - du moins pas dans toutes les situations. Si vous n'avez pas de valeur px fixe, calculez-en une par javascript et utilisez la bibliothèque de votre choix (comme jQuery, Greensock, etc.) pour la définir.

1
Hafenkranich

Il manque le -moz-transform-Origin de votre code CSS.

#test{
    -webkit-transform-Origin: 50% 50%;
    -moz-transform-Origin: 50% 50%;
    ...
}
0
Andrei Todorut

FWIW, j’ai pu résoudre mon problème avec Greensock, en utilisant TweenMax pour animer des chemins individuels à l’intérieur, et cela fonctionnait dans les navigateurs Firefox Gecko et Webkit (Safari/Chrome). mais cela a fonctionné pour moi)

Si j'avais un SVG à deux vitesses, je voulais tourner dans une autre forme. J'ai donc attribué à chaque engrenage un identifiant unique (id = "gear1", id = "gear2"), puis je les ai tournés avec Greensock, à peu près comme ceci:

TweenMax.to("#gear1", 3.2, { 
  repeat: -1, //repeat infintely 
  ease: Linear.easeNone,  //no easing, linear motion 
  rotation:360,  //amount to rotate (full) 
  transformOrigin:"center"  //transform Origin that WORKS :) 
});

Idem pour # gear2 avec un timing légèrement différent, et fonctionne très bien sur tous les navigateurs. 

0
Jesse

En outre, vous pouvez envisager de désactiver l’animation pour les versions de Firefox qui ne prennent pas en charge transform-box: fill-box.

Comme ça:

@supports (-moz-transform: rotate(0deg)) and (not (transform-box: fill-box)) {
    #test {
        animation: none;
    }
}

La première déclaration est juste pour vérifier si vous êtes sur firefox, car vous ne voulez pas le désactiver sur les autres navigateurs. La deuxième instruction vérifie si la propriété transform-box- est prise en charge par le navigateur. Je l'ai utilisé dans un projet en cours et cela fonctionne comme un charme.

0
SoBiT