web-dev-qa-db-fra.com

Mettre à l'échelle et refléter un objet SVG

Comment puis-je d'abord mettre à l'échelle un objet, disons 2 * fois sa taille actuelle, puis le retourner verticalement et horizontalement, ou les deux?

A partir de maintenant, je peux soit définir "scale (2,2)" pour qu'il devienne 2 fois plus grand que sa largeur et sa hauteur mais je ne peux pas le retourner en même temps avec scale (-1, 1) pour le retournement vertical .

Je crée des objets SVG par programme, en tant que format d'exportation.

47
Deukalion

Pour appliquer à la fois l'échelle et le retournement, il vous suffit de les lister dans votre transformation.

transform="scale(2,2) scale(-1,1)"

ou simplement combiner les valeurs

transform="scale(-2,2)"

Bien sûr, le problème que vous avez avec les échelles négatives est que les objets sont basculés sur l'origine (en haut à gauche) du fichier SVG, de sorte qu'ils peuvent disparaître du bord du document. Vous devez également corriger cela en ajoutant une traduction.

Ainsi, par exemple, imaginons que nous ayons un document 100x100.

<svg width="100" height="100">
    <polygon points="100,0,100,100,0,100"/>
</svg>

Pour retourner ceci verticalement nous faisons:

<polygon points="100,0,100,100,0,100" transform="scale(2,-2)"/>

et pour corriger le mouvement hors de l’écran, nous devons soit le décaler avant le retournement (pour qu’il soit retourné à l’écran):

<polygon points="100,0,100,100,0,100" transform="scale(2,-2) translate(0,-100)"/>

(La traduction est listée en second lieu ici car les listes de transformation sont effectivement appliquées de droite à gauche)

ou on peut le changer positivement (par la taille mise à l'échelle) après:

<polygon points="100,0,100,100,0,100" transform="translate(0,200) scale(-2,2)"/>

Voici une démo montrant le retournement vertical, le retournement horizontal et les deux retournements

Mettre à jour

Pour retourner (en position) un objet déjà existant quelque part à l’écran. Déterminez d’abord son cadre de sélection (minX, minY, maxX, maxY), ou centreX, centreY si vous le savez déjà à la place.

Puis ajoutez ce qui suit à sa transformation:

translate(<minX+maxX>,0) scale(-1, 1)   // for flip X
translate(0,<minY+maxY>) scale(1, -1)   // for flip Y

ou si vous avez le centre, vous pouvez utiliser

translate(<2 * centreX>,0) scale(-1, 1)   // for flip X

Donc dans votre exemple:

<rect x="75" y="75" width="50" height="50"  transform="translate(-100, -100) scale(2, 2) scale(1, 1) rotate(45, 100, 100)" />

Le minX + maxX vient à 200. Donc, pour retourner horizontalement, nous ajoutons:

translate(200,0) scale(-1, 1)

Donc l'objet final devient:

<rect x="75" y="75" width="50" height="50"  transform="translate(200,0) scale(-1, 1) translate(-100, -100) scale(2, 2) scale(1, 1) rotate(45, 100, 100)" />

démo ici

94
Paul LeBeau

Here est l'extrait de code Livescript-ish qui vous permet d'inverser et de mettre à l'échelle horizontalement un facteur quelconque:

    # scale is 1 by default

    if mirror or scale isnt 1
        [minx, miny, width, height] = svg.attributes.viewBox |> split-by ',' |> cast-each-as (Number)

        s = scale
        # container is the root `g` node 
        container.attributes.transform = if mirror
            "translate(#{s * (width + minx) + minx}, #{-miny * (s-1)}) scale(#{-s},#{s})"
        else
            "translate(#{-minx * (s-1)}, #{-miny * (s-1)}) scale(#{s},#{s})"

        if scale isnt 1
            svg.attributes
                ..viewBox = "#{minx},#{miny},#{width * scale},#{height * scale}"
                ..width = "#{width * scale}"
                ..height = "#{height * scale}"
0
ceremcem