GAZAR

Principal Engineer | Mentor

You can draw on the canvas by clicking and dragging your mouse.

Paper.js for Creating a Chain Effect in React TypeScript

Paper.js for Creating a Chain Effect in React TypeScript

The chain effect involves creating a series of interconnected shapes or objects that respond to user interaction or animation. Each element in the chain is connected to the next, creating a fluid and dynamic visual representation that can be manipulated or animated in real-time.

You can customize the appearance and behavior of the chain by adjusting parameters such as segment length, color, and thickness. Experiment with different settings to achieve the desired visual effect for your application.

const PaperJS = () => {
  const [paperJSLoaded, setPaperJSLoaded] = useState(false);
  const myCanvasRef = useRef(null);

  const loadPaperJS = async () => {
    const script = document.createElement("script");
    script.src =
      "https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.15/paper-full.min.js";
    script.async = true;
    document.body.appendChild(script);
    script.onload = () => {
      setPaperJSLoaded(true);
      console.log("PaperJS loaded");
    };
  };

  useEffect(() => {
    if (paperJSLoaded) {
      // @ts-ignore
      const paper = window.paper;
      paper.install(window);
      paper.setup(myCanvasRef.current);
      setTimeout(() => {
        const view = paper.view;
        const points = 25;
        const length = 10;

        const path = new paper.Path({
          strokeColor: "#E4141B",
          strokeWidth: 10,
          strokeCap: "round",
        });

        const start = view.center.divide([10, 1]);
        for (let i = 0; i < points; i++) {
          path.add(start + new paper.Point(i * length, 0));
        }

        const tool = new paper.Tool();
        tool.onMouseMove = function (event) {
          path.firstSegment.point = event.point;
          for (let i = 0; i < points - 1; i++) {
            const segment = path.segments[i];
            const nextSegment = segment.next;
            const vector = segment.point.subtract(nextSegment.point);
            vector.length = length;
            nextSegment.point = segment.point.subtract(vector);
          }
          path.smooth({ type: "continuous" });
        };

        tool.onMouseDown = function () {
          path.fullySelected = true;
          path.strokeColor = "#e08285";
        };

        tool.onMouseUp = function () {
          path.fullySelected = false;
          path.strokeColor = "#e4141b";
        };
      });
    } else {
      loadPaperJS();
    }
  }, [paperJSLoaded]);

  const RenderBoard = () => {
    return (
      <canvas
        id="myCanvas"
        ref={myCanvasRef}
        resize="true"
        data-paper-scope="1"
        style={{
          aspectRatio: "1/1",
          overflowClipMargin: "content-box",
          overflow: "clip",
          WebkitUserModify: "read-only",
          userSelect: "none",
          WebkitTapHighlightColor: "rgba(0, 0, 0, 0)",
          width: "100%",
          height: "100%",
        }}
      />
    );
  };

  return (
    <div>
      <Box border={"4px solid black"} width={"500px"} aspectRatio={1}>
        <RenderBoard />
      </Box>
    </div>
  );
};

export default PaperJS;

Paper.js provides developers with a versatile toolkit for creating dynamic and interactive visual effects like the chain in React TypeScript projects. By leveraging Paper.js's capabilities and integration with React, you can build engaging user interfaces that captivate and delight your audience.