reactjsraphael

The rendering order of the React-raphael components (like z-index)


I want the Raphael-react components to be drawn in the order I need (to create different layers or something like z-index). How can I control the position of components "Path" on the "Paper"?

This is a simplified view:

<Paper>
 <Set>
   <Path .../>
   <Path .../>
   <Path .../>
 </Set>             
</Paper>

Solution

  • It seems that Raphael doesn't support z-index, but you can achieve the goal if you keep all data in an array inside local state (or Redux):

      const [data, setData] = useState([
        { x: 50, y: 50, r: 40, attr: { stroke: "#0b8ac9", "stroke-width": 5 }},
        ... 
      ])
    

    Then if you'll want change z-Index of element just move it in array:

      zIndexOrder = [ ..., -1, 0, 1,  ...] // last element has big z-index
    

    I prepare demo for you with the Olympic Rings where I just shuffle them.

      const randomizeZIndex = () => {
        const temp = [...data];
        temp.sort(() => Math.random() - 0.5);
        setData(temp);
      };
    

    You can see it here

    Of course, random is useless. You need to maintain a zOrder on each element to work properly.

    And if you want work with all figures you can add polymorphism. And save the element's type (circle, line, etc.)

    const elements = [{
      type: "Rect",
      key: "FirstRect",
      zOrder: 0,
      options: {
         x:30, y:148, width:240,height:150, 
         attr:{"fill":"#10a54a","stroke":"#f0c620","stroke-width":5
       }
     }}, ...];
    

    Code would be like this:

    import React, {Fragment} from 'react';
    import { Raphael, Paper, Set, Rect, Line } from "react-raphael";
    
    const RaphaelElement = {
      Line: function line({options}) {
        return <Line {...options}/>; // react-raphael Line
      },
      Rect: function rect({options}) {
        return <Rect {...options}/>; // react-raphael Rect
      }
    }
    
    const AllElements = ({elements}) => {
      return (
         <Fragment>
          { // with polymorphism
            elements.map(({options, key, type}) => {
              const CurrRaphaelElement = RaphaelElement[type];
              return <CurrRaphaelElement key={key} options={options} />
            })
          }
         </Fragment> 
      )
    }