Search code examples
react-natived3.jsreact-native-svg

How to center an SVG within another SVG group


Below is the image of my wheel/circle that is dynamically created using d3

My goal is to center the golden icons inside the black rim.

Below is my code that loops over the arcs created using d3 and the Icon component nested in the SVG group is what I am trying to position center in the dark rim. The icon itself is an SVG. I do not want to position the icons absolutely because I feel it might cause layout issues later on.



      <LinearGradient
          start={{ x: 0.25, y: 0 }}
          style={styles.wheelGradient}
          colors={gradients.borderGradient}>

          <View style={styles.wheelWrapper}>
            <Svg
              width={rimSize}
              height={rimSize}
              viewBox={`0 0 ${screenWidth} ${screenWidth}`}
              style={{ transform: [{ rotate: `-${angleOffset}deg`}]}}>

              <G y={screenWidth / 2} x={screenWidth / 2}>
                {_rimPaths.map((arc, i) => {
                  const [x, y] = arc.centroid;

                  const Icon = spinWheelPrizes[i].icon;

                  return (
                    <G key={`arc-${i}`}>
                      <Path d={arc.path} fill={colors.color1} />
                      <G origin={`${x}, ${y}`}>
                        <G x={x} y={y}>
                          <Icon />
                        </G
                      </G>
                    </G>
                  );
                })}
              </G>
            </Svg>
          </View>
        </LinearGradient>

Solution

  • You can use transformations to position them. Instead of absolute positioning, try using a 'translate' transformation to adjust the icon's placement within the rim. I'm attaching a snippet for your reference.

    the 'transform' attribute shifts the icon's group to the centroid coordinates (x, y). The x and y attributes within the component help place the icon precisely in the center of the black rim. Adjust the iconWidth and iconHeight values to match your icon's dimensions

    <G key={`arc-${i}`}>
    
      <Path d={arc.path} fill={colors.color1} />
    
      <G transform={`translate(${x}, ${y})`}> {/* Apply translation */}
      
        {/* Adjust for the icon's size and position it at the center */}
        <Icon 
          width={iconWidth} 
          height={iconHeight} 
          x={-iconWidth / 2} // Offset by half the icon's width
          y={-iconHeight / 2} // Offset by half the icon's height
        />
      
      </G>
    
    </G>