If you'd like to add a shape to your page either for stylistic or functional purposes, the <Shape />
component is provided to achieve this.
It's capable of becoming most euclidean shapes and paths, and has options for rounding, inset, styles, and animations (powered by React Spring).
Shapes are created in <Svg>
elements, so they can be used alongside other <Shape />
components as well as other SVG elements. You can even use them in masks, and more complex SVG operations.
Since shapes utilise React Spring for their animations they must be imported from the nitpick-ui/client
entrypoint, which will pass a 'use client';
directive for its exports.
Demo
Making basic shapes
The shape component at its most basic breaks shapes down into...
| Prop | Type | Description |
|---|---|---|
| points | number | How many points the shape has, 3 for a triangle, 4 for a square, etc. |
width | number | The width of the shape. |
height | number | The height of the shape. |
| inset | number | How far back into the shape the space between each point returns. 0 for nothing, and 1 for completely (making your shape disappear). |
| rounded | number | How rounded the corners of the shape are as a percentage, 0 for none, and 100 for completely (making your shape an oval/circle). |
| rotate | number | How much to rotate the shape in degrees clockwise. |
There are many other props for making more fine-tuned shapes, which are available from the API page for the props or the code demos below.
Let's go through some examples of making basic shapes...
A square
To make a pointy square set points={4}
and rotate={45}
.
Circle
To make a humble circle set points={4}
and rounded={100}
.
Squircle
You can make a poor man's squircle by setting points={4}
, rounded={50}
, rotate={45}
, and inset={0.2}
.
It's not exact, but it's legally distinct also (maybe).
The shapes are limited of course, but you can make a lot of interesting designs through composition of multiple shapes, animations, colours, and CSS effects.
The API should be capable of most Material Design Expressive demos, for example.
Composition
<Shape />
components must be contained within a parent <Svg />
component (or your own <svg>
element), which allows you to compose multiple shapes together, as well as other SVG elements.
You can source <Svg />
from nitpick-ui/client
as well, which will also pass a 'use client';
directive.
Now you can compose multiple shapes together, and even use them in masks.
You can also add on CSS effects such as masks. Let's take some inspiration from Material Design's expressive shapes for a moment...
Animating shapes
As you've noticed from the above examples, shapes can be animated by passing props to them that change over time.
This is powered by React Spring, and so you can use any of the hooks or utilities from that library to animate your shapes since it's shipped as a peerDependency.
How to properly use React Spring is a long discussion, as is best practices in web animation generally, I won't go massively into detail here but the quick summary of Nitpicks animation opinions is...
Nitpicks rules of animations...
- Physics based animations are incredible when put next to what's in CSS. If your animatable element doesn't feel like it has weight, it's better off not being animated at all.
- Don't overuse animations, just because you can doesn't mean you should. Show restraint!
- Animated elements should respond to user events either directly or indirectly. If an element is animated without user input, it's worth thinking about how it can be made to respond to a user event should it arise (mouse over, etc.). People like to play.
Animations on shapes are physics based, you can pass the basics for your animation in the animation
prop. This prop accepts a few options based directly on animated
element in React Spring.
In short these are...
| Prop | Type | Description |
|---|---|---|
| to | object | The target values to animate to, e.g. { rotate: 360 } . |
| from | object | The starting values to animate from, e.g. { rotate: 0 } . |
| config | object | function | string | A config object or function that returns a config object for the animation. See the React Spring docs for full details. |
| reset | boolean | Whether to reset the animation when the to prop changes. |
| reverse | boolean | Whether to reverse the animation when the to prop changes. |
| immediate | boolean | function | Whether to skip the animation and jump to the end state immediately. |
| delay | number | A delay in milliseconds before the animation starts. |
| onStart | function | A callback function that is called when the animation starts. |
| onRest | function | A callback function that is called when the animation ends. |