Distort a container by using css 3D transforms for projection mapping and software keystone for react.
- Distort any container by using a rectangle
- Centralized control and update of multiple containers
- Split up containers into tiles
Install via npm
npm install react-projection-mapping --save
Wrap your application with Projection
.
import { Projection } from "react-projection-mapping";
<Projection data={data} onChange={update} editing={true} enabled={true}>
Your containers
</Projection>;
Use the onChange
prop to save the current values.
const update = ({ values, action }) => {
if (action === "onEnd") {
localStorage.setItem("projection", JSON.stringify(values));
}
};
data
allows you to load the values from an endpoint.
const [items, setItems] = useState();
useEffect(() => {
const data = JSON.parse(localStorage.getItem("projection"));
if (data) {
setItems(data);
}
}, []);
Each Element you want to distort should wrapped with Layer
. Make sure to add an unique id
.
import { Layer } from "react-projection-mapping";
<Layer id="total">Element</Layer>;
Use the SplitLayer
component to separate the Layer into multiple other layers. It renders the same component multiple times and uses clip-path to split it. It can take all settings from Layer
.
import { Projection, SplitLayer } from "react-projection-mapping";
<Projection data={data} onChange={update} edit={true} enabled={true}>
{[...Array(2)].map((y, index) => (
<SplitLayer
key={index}
id={`tile-${index}`}
clip={[0, index === 0 ? 50 : 0, 0, index === 0 ? 0 : 50]}
>
Content
</SplitLayer>
))}
</Projection>;
Hook to get the current distort status or manually set it from any place inside Projection
.
import { useProjection } from "react-projection-mapping";
const {
data,
edit,
enabled,
selectedCorner,
selectedLayer,
setSelectedCorner,
setSelectedLayer,
} = useProjection();
Results from the useProjection()
hook
{
"data": {
"id-of-layer": {
"corners": [
-326, 175, -212, 93, -184, 236, -73, 157
],
"zIndex": 3
}
},
"edit": true,
"enabled": true,
"selectedCorner": 0,
"selectedLayer": "id-of-layer",
"setSelectedCorner": () => { return number},
"setSelectedLayer": () => {return "id-of-layer" }
}
While in editing mode you can use the keyboard shortcuts for fine adjustments.
Q
move to next cornerW
move to previous cornerA
move z-index downwardsS
move z-index upwards↑
→
←
↓
Move corner⇧
+↑
→
←
↓
Move corner 10px