Question Comment calcule-t-on la méthode getBBox () SVGRect?


j'ai un g élément qui contient un ou plusieurs path éléments. Comme je l'ai mentionné dans une autre question, Je redimensionne et traduit le g élément en calculant un transform attribut pour qu'il tienne sur une grille dans une autre partie du canevas.

Le calcul est fait en utilisant la différence entre deux rectangles, le getBBox() du g élément et le rectangle autour de la grille.

Voici la question - après avoir fait la transformation, je mets à jour le contenu du g élément et appel getBBox() encore, sans pour autant enlever le transform. Le rectangle résultant semble être calculé sans tenir compte de la transform. Je m'attendais à ce qu'il reflète le changement. Ce comportement est-il compatible avec la spécification SVG? Comment puis-je obtenir la boîte englobante du rectangle transformé?

Ceci, BTW, se trouve dans un document HTML 5 exécuté dans Firefox 4, si cela fait une différence.

Mise à jour: Apparemment, ce comportement semble clairement en violation de la spécification. Du texte ici à w3c:

SVGRect getBBox ()

Retourne la boîte englobante étroite dans l'espace utilisateur actuel (c'est-à-dire après l'application de l'attribut de transformation, le cas échéant) sur la géométrie de tous les éléments graphiques contenus, à l'exception des effets de trait, de découpage, de masquage et de filtre). Notez que getBBox doit renvoyer le cadre de sélection réel au moment de l'appel de la méthode, même si l'élément n'a pas encore été rendu.

Est-ce que je lis ceci correctement? Si c'est le cas, cela semble être un errata dans l'implémentation SVG utilisée par Firefox; Je n'ai pas eu l'occasion d'essayer d'autres. Je classerais un rapport de bogue si quelqu'un pouvait m'indiquer où.


36
2018-05-30 17:31


origine


Réponses:


Le comportement que vous voyez est correct et conforme aux spécifications. La transformation est appliquée, puis la bbox est calculée en "unités d'utilisateur actuelles", c'est-à-dire l'espace utilisateur actuel. Donc, si vous voulez voir le résultat d'une transformation sur l'élément, vous devez regarder la bbox d'un nœud parent ou similaire. C'est un peu déroutant, mais expliqué beaucoup mieux dans le Spécification SVG Tiny 1.2 pour SVGLocatable Cela contient un certain nombre d’exemples qui clarifient ce qu’il est censé faire.


14
2018-06-09 05:44



Les gens sont souvent désorientés par la différence de comportement entre getBBox et getBoundingClientRect.

getBBox est la méthode native d'un élément SVG équivalente à la recherche de l'élément offset / clientwidth de HTML DOM. La largeur et la hauteur est ne jamais changer même lorsque l'élément est pivoté. Il ne peut pas être utilisé pour les éléments DOM HTML.

getBoundingClientRect est commun aux deux éléments HTML et SVG. le rectangle borné largeur et hauteur va changer lorsque l'élément est pivoté ou lorsque plusieurs éléments sont regroupés.


14
2017-11-07 13:26



il y a au moins 2 manières simples mais quelque peu piratées de faire ce que vous demandez ... s'il y a des manières plus intéressantes (moins de piratage), je ne les ai pas encore trouvées

EASY HACKy # 1:
a) configurer un rect correspondant à la bbox "non transformée" que group.getBBox () renvoie
b) appliquer la "transformation non appliquée" du groupe à ce rect
c) rect.getBBox () devrait maintenant retourner la bbox que vous recherchez

EASY HACKY # 2: (seulement testé en chrome)
a) utiliser element.getBoundingClientRect (), qui renvoie suffisamment d’informations pour que vous puissiez construire la bbox que vous recherchez


6
2017-07-29 18:55



Apparemment, getBBox () ne prend pas en compte les transformations.

Je peux vous indiquer ici, malheureusement je n'ai pas réussi à le faire fonctionner: http://tech.groups.yahoo.com/group/svg-developers/message/22891


4
2018-06-04 01:30



Les groupes SVG ont une mauvaise pratique: ne pas accumuler toutes les transformations effectuées. J'ai ma façon de faire face à ce problème. J'utilise mes propres attributs pour stocker les données de transformation actuelles que j'inclus dans toute transformation ultérieure. Utilisez des attributs compatibles XML tels que alttext, value, name .... ou simplement x et y pour stocker la valeur accumulée comme attribut.

Exemple:

<g id="group" x="20" y"="100" transform="translate(20, 100)">
<g id="subgroup" alttext="45" transform="rotate(45)">
<line...etc...

Donc quand je fais des transformations Je prends ces valeurs d'attributs faits à la main, et en l'écrivant, j'écris à la fois la transformation et la même valeur avec les attributs que j'ai créés pour conserver toutes les valeurs accumulées.

Exemple de rotation:

function symbRot(evt) {

 evt.target.ondblclick = function () {

 stopBlur();
 var ptx=symbG.parentNode.lastChild.getAttribute("cx");
 var pty=symbG.parentNode.lastChild.getAttribute("cy");
 var currRot=symbG.getAttributeNS(null, "alttext");

 var rotAng;
 if (currRot == 0) { rotAng = 90 } else if (currRot == 90) { rotAng = 180 } else if (currRot == 180) { rotAng = 270 } else if (currRot == 270) { rotAng = 0 };
 symbG.setAttributeNS(null, "transform", "rotate(" + rotAng + "," + ptx + ", " + pty + ")");
 symbG.setAttributeNS(null, "alttext", rotAng );
 };
} 

3
2017-12-23 14:50



J'ai créé une fonction d'assistance, qui renvoie diverses métriques de l'élément svg (également bbox de l'élément transformé).

Le code est ici: https://stackoverflow.com/a/13111598/1691517

et exemple fonctionnel complet est ici: http://jsbin.com/acowaq/1


2
2017-12-08 18:44