2017-10-10 13 views
1

J'ai certains SVG qui ont un attribut defs avec des balises style à l'intérieur. Comme ceci:SVG en JSX - comment convertir les balises defs

<svg ...> 
    <defs> 
    <style>.cls-1,.cls-7{fill:#b2488d;}.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6{stroke:#671f4d;}</style> 
    </defs> 
    ... 
</svg> 

Je veux utiliser ces SVGs dans React, donc je veux les convertir en JSX valide. J'ai déjà utilisé des outils comme svg2jsx, mais ils dépouillent le tag defs de sorte qu'aucun des attributs de style ne sont plus présents. Est-il un moyen de préserver le defs avec l'étiquette style à l'intérieur en convertissant le SVG en JSX? Ou n'est-il pas possible d'utiliser des classes css dans ce cas?

+0

Do vous devez le convertir? Vous ne pouvez pas utiliser '' dans votre fichier html ou 'background-image: url ("/images/logo.svg ");' dans votre css? – cyonder

+0

@cyonder Les SVG Inline sont mieux supportés dans la plupart des navigateurs – lumio

+0

Je veux utiliser des SVG pour manipuler les attributs. – feychou

Répondre

1

Si vous avez créé votre fichier SVG dans Illustrater, enregistrez-le avec Propriétés CSS défini sur Presentation Attributes. De cette façon, vous ne finirez pas avec des classes CSS et vous pourrez directement modifier tous les attributs.

J'exporté un SVG qui ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?> 
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> 
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 
    viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"> 
<g> 
    <rect x="15.5" y="15.5" fill="#FFFFFF" width="44" height="44"/> 
    <path d="M59,16v43H16V16H59 M60,15H15v45h45V15L60,15z"/> 
</g> 
<g> 
    <path fill="#FFFFFF" d="M60.5,81.5c-12.1,0-22-9.9-22-22s9.9-22,22-22s22,9.9,22,22S72.6,81.5,60.5,81.5z"/> 
    <path d="M60.5,38C72.4,38,82,47.6,82,59.5S72.4,81,60.5,81S39,71.4,39,59.5S48.6,38,60.5,38 M60.5,37C48.1,37,38,47.1,38,59.5 
     S48.1,82,60.5,82S83,71.9,83,59.5S72.9,37,60.5,37L60.5,37z"/> 
</g> 
</svg> 

je puis me suis débarrassé de toutes les balises inutiles et juste utilisé dans mon élément:

const Image = (props) => { 
 
    const { 
 
    hideSquare, 
 
    hideCircle, 
 
    } = props; 
 
    
 
    const colorSquare = props.colorSquare || '#fff'; 
 
    const colorCircle = props.colorCircle || '#fff'; 
 
    
 
    return (
 
    <svg x="0px" y="0px" viewBox="0 0 100 100"> 
 
     { hideSquare ? null : (
 
     <g> 
 
      <rect x="15.5" y="15.5" fill={ colorSquare } width="44" height="44"/> 
 
      <path d="M59,16v43H16V16H59 M60,15H15v45h45V15L60,15z"/> 
 
     </g> 
 
    ) } 
 
     { hideCircle ? null : (
 
     <g> 
 
      <path fill={ colorCircle } d="M60.5,81.5c-12.1,0-22-9.9-22-22s9.9-22,22-22s22,9.9,22,22S72.6,81.5,60.5,81.5z"/> 
 
      <path d="M60.5,38C72.4,38,82,47.6,82,59.5S72.4,81,60.5,81S39,71.4,39,59.5S48.6,38,60.5,38 M60.5,37C48.1,37,38,47.1,38,59.5 
 
      S48.1,82,60.5,82S83,71.9,83,59.5S72.9,37,60.5,37L60.5,37z"/> 
 
     </g> 
 
    ) } 
 
    </svg> 
 
); 
 
}; 
 

 
class Wrapper extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    
 
    // Set default state 
 
    this.state = { 
 
     selectedColor: 'lightgreen', 
 
     hideSquare: false, 
 
     hideCircle: false, 
 
    }; 
 
    } 
 
    
 
    // onInput callback 
 
    changeColor = (e) => { 
 
    this.setState({ selectedColor: e.target.value }); 
 
    } 
 
    
 
    changeVisibility = (e) => { 
 
    const { name, checked } = e.target; 
 
    this.setState({ [ name ]: checked }); 
 
    } 
 
    
 
    render() { 
 
    return (
 
     <div> 
 
     <select onInput={ this.changeColor }> 
 
      <option>lightgreen</option> 
 
      <option>pink</option> 
 
      <option>red</option> 
 
     </select><br /> 
 
     <label><input type="checkbox" name="hideSquare" onChange={ this.changeVisibility } /> hideSquare</label> 
 
     <label><input type="checkbox" name="hideCircle" onChange={ this.changeVisibility } /> hideCircle</label><br /> 
 
     <Image 
 
      hideSquare={ this.state.hideSquare } 
 
      hideCircle={ this.state.hideCircle } 
 
      colorSquare={ this.state.selectedColor } 
 
      colorCircle={ this.state.selectedColor } 
 
     /> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
ReactDOM.render(<Wrapper />, document.getElementById('app'));
svg { 
 
    width: 200px; 
 
    height: 200px; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<div id="app"></div>

+0

Est-ce que ce dernier me permettrait de changer les valeurs d'attribut avec les valeurs d'état de réaction? Comme dans, l'interpolation de chaîne fonctionnerait-elle? – feychou

+0

J'ai mis à jour ma réponse. tl; dr: Vous devez exporter votre fichier SVG sans générer de styles CSS. :) – lumio

+0

Cela ne répond pas exactement à ma question, mais j'ai trouvé que c'était une bonne solution pour mon problème. – feychou