Home > Software engineering >  Add attributes to a path svg component for a map in React
Add attributes to a path svg component for a map in React

Time:10-13

I am trying to implement a strategy game that uses a svg map that I created and I would like to add some attributes like "troops" in each "path"(which would be the territory) and some other props. Is it possible to add att(props) to only a path and then use this component inside a svg tag which is the whole map. So basically I want to know how can I create a territory object with att(props) and an input or label in the map, so later I can add onClick events and other events.

For now I have the component Map and also the Territory component(I am not sure if it's the best way to deal with it.)

const Territory = ({ tD }) => {
  const [color, setColor] = useState('red')
  const [troops, setTroops] = useState(21)

  return (
    <>
      <input type="text" />
      <path fill-rule="evenodd" clip-rule="evenodd" d={tD} fill={color} stroke="black" />
    </>
  );
};

export default Territory;

const Map = () => {
  return (
    <svg width="1397" height="686" viewBox="0 0 1397 686" fill="none" xmlns="http://www.w3.org/2000/svg">
      {territories.map(territory => (
        <Territory key={territory.id} tD={territory.tD} />
      ))}
    </svg>

  );
};

I want to add the troops to be visible(number) in an input or label in the map for each territory. something like this map with inputs

Is it possible to do it? what would be the best approach to build a territory component which has props like "troops"

Thank you so much whoever helps me.

CodePudding user response:

You are rendering normal HTML <input /> as a part of svg, This doesn't work. If anything is not a part of svg and you're rendering it as a child of svg then you have to wrap it as a foreignObject.

Territory Component

const Territory = ({ tD }) => {
  const [color, setColor] = useState('red')
  const [troops, setTroops] = useState(21)

  return (
    <g>
      <foreignObject x="40" y="40" width="100" height="100">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <input type="text" />
        </div>
      </foreignObject>
      <path fill-rule="evenodd" clip-rule="evenodd" d={tD} fill={color} stroke="black" />
    </g>
  );
};

Note:

  • Don't forget the height and width attributes. You may also need x & y too.
  • Don't forget xmlns="http://www.w3.org/1999/xhtml" on the container HTML element.
  • You can use svg <g /> tag to group the elements.
  • Related