Creating circular menus with react-planet
Today we are happy to introduce a new open source library for react that allows you to build circular menus in a very easy and handy way.
The highly customizable lib can be found here: https://github.com/innFactory/react-planet
Live-Demo: https://innfactory.github.io/react-planet
In the following article we will show you some examples and give you an overview of the possibilities and functionalities of react-planet.
The concept
The name “planet” let you think about things like orbit or satellites. So with this naming the concept is very easy to understand. In the middle we always have a planet. The planet is the base component of the lib. It has a various amount of satellites around which you can pass as react children. The satellites stick to one orbit which can be hidden. If a planet switches from state close to open, the orbit and the satellites fly out to the given radius.
Install the npm package and add it to your project
Just install react-planet with the following line. Type this into your terminal while you are in your project folder:
npm install — save react-planet
Basic Example
The following example is made with just a few lines of code. The planet component can take any divs as children and render it as satellites. The planet component is defined with the centerComponent
. With the prop autoclose
the planet handles the open state by itself. Alternatively, you can handle the open state from outside with the open
, onClick
and onClose
props.
import { Planet } from 'react-planet';export function MyPlanet() { return ( <Planet centerContent={ <div style={{ height: 100, width: 100, borderRadius: '50%', backgroundColor: '#1da8a4', }}/>} open autoClose > <div style={{ height: 70, width: 70, borderRadius: '50%', backgroundColor: '#9257ad', }}
/> <div style={{ height: 70, width: 70, borderRadius: '50%', backgroundColor: '#9257ad',
}} /> </Planet> );}
Change the orbit
With the props orbitRadius
you can change how far the satellites can fly out. If you also set a rotation angle the satellites will have a different position.
<Planet centerContent={div style={...yourStlye}/>}
open
orbitRadius={120}
rotation={30}
>
You also can hide the orbit with the hideOrbit
boolean prop. But now we will look how a custom orbit is made. With the prop orbitStyle
you can set a function which receives the default orbit style. This default style can be overwritten partially or replaced completely. In the following example we override some css styles. Btw if you want to have more satellites you only have to add some more div to the planet’s children.
<Planet
orbitStyle={defaultStyle => ({
...defaultStyle,
borderWidth: 4,
borderStyle: 'dashed',
borderColor: '#6f03fc',
})}
centerContent={<div className={classes.planetSmall} />}
open
>
<div className={classes.satellite1} />
<div className={classes.satellite2} />
<div className={classes.satellite3} />
</Planet>
Weird satellites and their orientation
If you have made some very special shapes for the satellites you may want to keep the angle where a satellite is placed and rotate it. For this case you can set the rotation behavior with the satelliteOrientation
prop to “DEFAULT”, “INSIDE”, “OUTSIDE”
or “READABLE”
. The last one is a mix between inside and outside. The top satellites are turned inside and the bottom ones are turned outside so it’s comfortable to read the text on it.
<Planet
// set one of the orientations
satelliteOrientation="INSIDE"
Bring it to life
You can give the planet a little organic behavior if you set the satellites or the planet dragable. There is always a combination of the prop dragablePlanet
and dragRadiusPlanet
(dragableSatellites
and dragRadiusSatellites
) where you can set the drag ability and with the radius the intensity. In addition the planet will bounce on open state changes if the prop bounce
is set.
<Planet
dragablePlanet
dragRadiusPlanet={20}
bounce
Planetception
Theoretically you could build a whole file explorer with react-planet. You can nest a planet into a planet, into a planet and into a planet… So a planet can also be a satellite. This brings us to following example which shows some kind of submenu.
Fake the space
If you plan to make half things only you can add some empty divs to your planet. Invisible divs takes the same space as the visible ones. Combine this behavior with the rotation prop and you get something like the following example:
<Planet
centerContent={<YourButton0 />}
hideOrbit
autoClose
orbitRadius={60}
bounceOnClose
rotation={105}
// the bounce direction is minimal visible
// but on close it seems the button wobbling a bit to the bottom
bounceDirection="BOTTOM"
>
<YourButton1 />
<YourButton2 />
<YourButton3 />
<div />
<div />
<div />
<div />
</Planet>
Alter the physics
We have seen the we could change the drag and bounce by the specific radius. The open and close mechanism could be altered by setting different physic values. The library behind the animation is react-spring (which has an awesome hook api). We exposed the values of the react-spring animation to the planet so you can change it by yourself:
<Planet
mass={4}
tension={500}
friction={19}
Summary
To the code: https://github.com/innFactory/react-planet
Live-Demo: https://innfactory.github.io/react-planet