Bonjour,

J'essaie depuis quelques heures d'importer un svg et de le modifier avec React. Mon but est de remplir mon svg avec une image.

Là où j'en suis

Je me suis fais un composant Svg pour charger un svg depuis une url.
Je profite de l'imbrication des svg pour charger mon Svg dans un svg parent qui contient déjà une pattern de mon image.
Au chargement de mon Svg je lui applique un fill avec l'url de mon pattern.
Si je prend le resultat du code à part et que je l'ouvre mon svg s'affiche bien.
Je vous met pas tout le code mais juste les éléments essentiels.


    const handleLoadSvg = () => {

        const svg = svgEl.current.children[0]

        // Suppression de tous les groupes vides
        Array.from(svg.children).forEach(el => {

            if(el.nodeName === 'g' && el.children.length === 0)
                el.parentNode.removeChild(el)

        })

        // Création d'un group qui englobe tous les éléments
        const group = document.createElement('g')
        group.setAttribute('fill', 'url(#svg-bg)')

        Array.from(svg.children).forEach(el => {
            el.removeAttribute('fill')
            group.appendChild(el)
        })

        svg.appendChild(group)

    }

    return (
            <div>
                <svg>
                    <defs>
                        <pattern id="svg-bg" width="100" height="100" patternUnits="userSpaceOnUse">
                        <image x="0" y="0" width="100" height="100" xlinkHref="https://media.prod.mdn.mozit.cloud/attachments/2012/07/09/2917/6d913d90e74b1eb6a59761cc8df61bfc/fxlogo.png"></image>
                        </pattern>
                    </defs>
                    {state.file ? <Svg ref={svgEl} url={state.file} onLoaded={handleLoadSvg}/> : <></>}
                </svg>
            </div>
    )

state.file est par défaut null et modifié via un reducer actionné par un autre composant et (pour l'instant) sa valeur change à 'https://image.flaticon.com/icons/svg/85/85523.svg' juste pour les tests.

Le code fonctionnel

Si vous prennez ce svg (qui est egal au svg que j'obtiens via React) il s'affiche correctement.

    <svg>
        <defs>
            <pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
              <image xlink:href="https://media.prod.mdn.mozit.cloud/attachments/2012/07/09/2917/6d913d90e74b1eb6a59761cc8df61bfc/fxlogo.png" x="0" y="0" width="100" height="100" />
            </pattern>
        </defs>
        <svg>
            <svg version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 479.861 479.861" style="enable-background:new 0 0 479.861 479.861;" xml:space="preserve">
                <g fill="url(#img1)">
                    <path d="..."></path>
                </g>
            </svg>
        </svg>
    </svg>

Je me demande bien si ça vient de React et de son shadow dom ?! Si oui il y a un moyen de contourner ça ?

Merci pour vos réponses

Aucune réponse