J'ai besoin de redimensionner et de faire pivoter certains éléments d'un document SVG à l'aide de javascript. Le problème est que, par défaut, il applique toujours la transformation autour de l'origine en (0, 0)
haut à gauche.
Comment redéfinir ce point d'ancrage de transformation?
J'ai essayé d'utiliser l' transform-origin
attribut, mais cela n'affecte rien.
Voici comment je l'ai fait:
svg.getDocumentById('someId').setAttribute('transform-origin', '75 240');
Il ne semble pas définir le point pivot au point que j'ai spécifié bien que je puisse voir dans Firefox que l'attribut est correctement défini. J'ai essayé des choses comme center bottom
et 50% 100%
avec et sans parenthèses. Rien n'a fonctionné jusqu'à présent.
Quelqu'un peut-il aider?
svg
coordinate-transformation
CTheDark
la source
la source
Réponses:
Pour faire pivoter, utilisez
transform="rotate(deg, cx, cy)"
, où deg est le degré que vous souhaitez faire pivoter et (cx, cy) définit le centre de rotation.Pour la mise à l'échelle / redimensionnement, vous devez traduire par (-cx, -cy), puis mettre à l'échelle et ensuite traduire en (cx, cy). Vous pouvez le faire avec une transformation matricielle :
Où sx est le facteur d'échelle sur l'axe des x, sy sur l'axe des y.
la source
Si vous pouvez utiliser une valeur fixe (pas "center" ou "50%"), vous pouvez utiliser CSS à la place:
Certains navigateurs (comme Firefox) ne gèrent pas correctement les valeurs relatives.
la source
element.setAttribute('transform-origin', '25px 25px')
?Si vous êtes comme moi et que vous souhaitez effectuer un panoramique et un zoom avec l'origine de la transformation, vous aurez besoin d'un peu plus.
Ici, cela fonctionne: http://forresto.github.io/dataflow-prototyping/react/
la source
id
correspondances dans l' attributgetElementById
et les documentsid="..."
. Il est difficile de savoir avec certitude sans voir le code. Si vous ne voulez pas le publier en tant que question SO, vous pouvez essayer de créer l'exemple le plus simple en utilisant vos noms d'attributs jusqu'à ce que cela fonctionne / que vous trouviez le problème, puis ajoutez le reste.Pour une mise à l'échelle sans avoir à utiliser la
matrix
transformation:Et le voici en CSS:
la source
il semble que nous ayons tous manqué un truc ici:
transform-box: fill-box
en utilisant
transform-box: fill-box
, un élément dans un SVG se comportera comme un élément HTML normal. Ensuite, vous pouvez postulertransform-origin: center
(ou autre chose) comme vous le feriez normalementc'est vrai,
transform-box: fill-box
pas besoin de trucs matriciels compliquésla source
transform-box: fill-box;
vous pouvez faire respecter les éléments svg d'transform-origin
une manière saine / comme vous vous en doutez !J'ai eu un problème similaire. Mais j'utilisais D3 pour positionner mes éléments, et je voulais que la transformation et la transition soient gérées par CSS. C'était mon code d'origine, que j'ai fait travailler dans Chrome 65:
Cela m'a permis de définir les
cx
,cy
et lestransform-origin
valeurs en javascript en utilisant les mêmes données.MAIS cela n'a pas fonctionné dans Firefox! Ce que je devais faire était envelopper la
circle
dans l'g
étiquette ettranslate
en utilisant la même formule de positionnement d' en haut. J'ai ensuite ajouté lecircle
dans lag
balise et défini ses valeurscx
etcy
sur0
. À partir de là,transform: scale(2)
serait mis à l'échelle du centre comme prévu. Le code final ressemblait à ceci.Après avoir apporté ce changement, j'ai changé mon CSS pour cibler le
circle
plutôt que le.dot
, pour ajouter letransform: scale(2)
. Je n'avais même pas besoin d'être utilisétransform-origin
.REMARQUES:
J'utilise
d3-selection-multi
dans le deuxième exemple. Cela me permet de passer un objet au.attrs
lieu de le répéter.attr
pour chaque attribut.Lorsque vous utilisez un littéral de modèle de chaîne, tenez compte des sauts de ligne, comme illustré dans le premier exemple. Cela inclura une nouvelle ligne dans la sortie et peut casser votre code.
la source
svg:transform-origin.enabled
préférence dans laabout:config
page de Firefox . Mais ... cela ne semblait pas être une solution adéquate. J'ai également trouvé une différence entretransform-origin: 50% 50%
ettransform-origin: center center
.