Rendering Primitives
After all, you need to utilize the primitive created and rendering them out is definitely the thing.
Unlike other frontend UI library, react-use-polygon
does not render the primitive to UI directly for you. Or locked you into using their rendering method only.
react-use-polygon
instead wishes to give you the flexibility by provide you minimum-opinionated primitive data.
To smoothen the process, you can utilize the primitive properties, includes: svgPath
, drawOnCanvas
and boundingBox
.
Rendering with SVG
One of the simplest ways to visualize the primitives is through SVG image.
Hence, svgPath
and boundingBox
properties of the primitive come in handy.
svgPath
string
As the name tells, it is a string representing SVG path and can be easily pass in as props for a path
element.
const { svgPath } = useCircle();
return (
<svg>
<path d={svgPath} />
</svg>
);
However, you may face a weird issue, which the primitive is not being rendered completely.
i.e. when using useCircle
:
The reason is simple, because the primitive is being drawn on origin (0, 0) and some part may end up in the negative plane, see more details.
You can either:
- Set the SVG style to
overflow: visible
(not always recommended). - Use
boundingBox
as theviewBox
property of SVG element. - Clip entire polygon onto positive plane.
- Use a simple SVG renderer (to do them for you).
Apart from 1, which we not recommend, 2, 3 and 4 can be done easily yourself, or using our built-in utilities.
Create SVG viewBox
from boundingBox
You can transform a primitive boundingBox
to SVG viewBox
by:
const { x, y, width, height } = boundingBox;
// Can be used as <svg viewBox={viewBox} ...
const viewBox = `${x} ${y} ${width} ${height}`;
You can convert the above to a function or use our built-in utility hook:
import { useSquare, useSVGViewBox } from "react-use-polygon";
const { boundingBox } = useSquare();
const viewBox = useSVGViewBox({ boundingBox });
<svg viewBox={viewBox} />;
or helper function:
import { computeSVGViewBox } from "react-use-polygon";
<svg viewBox={computeSVGViewBox({ boundingBox })} />;
Rather than pass in the props as { boundingBox }
, you can pass in primitive or even an array or primitives as well.
const rectangle = useRectangle();
const circle = useCircle({ position: { x: 50, y: 50 } });
// Directly pass in primitive
const viewBox = useSVGViewBox(rectangle);
// Or multiple primitives
const combinedViewBox = useSVGViewBox([rectangle, circle]);
Passing in an array is very helpful when you wish to render multiple primitive paths inside one SVG element.
Example of using useSVGViewBox
:
View useSVGViewBox
demo code
useSVGViewBox
demo codeimport { BasicSVGRenderer, useCircle, useSVGViewBox } from "react-use-polygon";
import styles from "./styles.module.css";
export default function SVGPartiallySeenFixed() {
const circle = useCircle();
const viewBox = useSVGViewBox(circle, { padding: { x: 100, y: 25 } });
return (
<BasicSVGRenderer
className={styles.partiallySeenFixed}
primitives={circle}
viewBox={viewBox}
/>
);
}
boundingBox
of primitive does not take into account of line stroke. Hence, when converted to SVG viewBox
, line stroke may only be partially shown.
To fix this issue, you can utilize padding
props in those function, which will make the box larger to accommodate the line stroke of SVG path.
Please refer useSVGViewBox.
Clip entire polygon onto positive plane
Another way is to clip the entire primitive (or at least the interested part) onto the positive plane by using position
configurations. For example,
Before:
import { useCircle } from "react-use-polygon";
// viewBox: "-100 -100 200 200"
const circle = useCircle({ radius: 100 });
After:
import { useCircle } from "react-use-polygon";
// viewBox: "0 0 200 200"
const circle = useCircle({ radius: 100, position: { x: 100, y: 100 } });
As you can see that, adding a position
config can move the polygon to you desired location on the plane.
You can even hide part of the faces by moving them to negative plane if you don't want to show on the negative part in the viewBox
.
Use a simple svg renderer
You can create your own rendering component or use one of our built-in SVG renderers.
import { usePolygon, BasicSVGRenderer } from "react-use-polygon";
export function MyComponent() {
const triangle = usePolygon({ sides: 3 });
const square = usePolygon({ sides: 4 });
const pentagon = usePolygon({ sides: 5 });
return (
<BasicSVGRender
className="MyComponent"
primitives={[triangle, square, pentagon]} // You can put it one or an array of primitives
pathProps={{ fill: "blue", stroke: "red", strokeWidth: 2 }} // Path props
viewBoxOptions={{ padding: 8 }}
// ... other SVG props
/>
);
}
Built-in renderers are very simple component that help you getting started easier. You don't even need to use them too.
For more, please have a look at built-in renderers.