Skip to content

wirewirewirewire/react-projection-mapping

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-projection-mapping

Distort a container by using css 3D transforms for projection mapping and software keystone for react.

Demo application ℹ️

Features 🌟

  • Distort any container by using a rectangle
  • Centralized control and update of multiple containers
  • Split up containers into tiles

Usage 🖼️

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>;

Saving values 💾

Use the onChange prop to save the current values.

const update = ({ values, action }) => {
  if (action === "onEnd") {
    localStorage.setItem("projection", JSON.stringify(values));
  }
};

Get 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);
  }
}, []);

Layer

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>;

SplitLayer

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>;

useProjection() hook

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" }
}       

Keyboard control

While in editing mode you can use the keyboard shortcuts for fine adjustments.

  • Q move to next corner
  • W move to previous corner
  • A move z-index downwards
  • S move z-index upwards
  • Move corner
  • + Move corner 10px

Inspired by