How to use PaperJs with React?
Asked Answered
L

5

11

I am trying to use PaperJs in one of my React components. I'm not sure where to use the paper.view.onFrame method in my component

Lenin answered 18/5, 2019 at 10:1 Comment(0)
H
7

https://github.com/react-paper/react-paper-bindings

There's a package for you to see how paperjs and reactjs being implemented together.

You can use the package as is (last update seems a bit fine on december 2018), or you can see how the author implementing paperjs into a reactjs project.

Haphazard answered 18/5, 2019 at 10:13 Comment(0)
V
15

For those who are looking for using paperjs in create-react-app with hooks.

App.js

import Canvas from './Canvas';
import './App.css';

function App() {
  return (
    <div>
      <Canvas />
    </div>
  );
}

export default App;

Canvas.js

import React, { useRef, useEffect } from 'react';
import Paper from 'paper';
import draw1 from '../drawings/draw1';

const Canvas = props => {
  
  const canvasRef = useRef(null)
  
  useEffect(() => {
    const canvas = canvasRef.current;
    Paper.setup(canvas);
    draw1();
  }, []);
  
  return <canvas ref={canvasRef} {...props} id="canvas" resize="true" />
}

export default Canvas;

draw1.js

import Paper from "paper";

const draw1 = () => {
  let myPath = new Paper.Path();

  Paper.view.onMouseDown = (event) => {
    myPath.strokeColor = "white";
    myPath.strokeWidth = 3;
  };

  Paper.view.onMouseDrag = (event) => {
    myPath.add(event.point);
  };

  Paper.view.draw();
};

export default draw1;
Viridian answered 24/10, 2020 at 7:42 Comment(1)
When I do this I get ModuleNotFoundError: Module not found: Error: Can't resolve 'jsdom/lib/jsdom/living/generated/utils' in '.../node_modules/paper/dist/node' Did you experience this? How can I get around this? I use gatsbyTish
H
7

https://github.com/react-paper/react-paper-bindings

There's a package for you to see how paperjs and reactjs being implemented together.

You can use the package as is (last update seems a bit fine on december 2018), or you can see how the author implementing paperjs into a reactjs project.

Haphazard answered 18/5, 2019 at 10:13 Comment(0)
B
2

My 2 cents, hope this helps.

Say you have a MainView components like:

import React, {Component} from 'react';
import Sketch from './Sketch';

export default class MainView extends Component {

render() {
    return(
        <div>
            <canvas id='paper-canvas' resize='true' />
            <Sketch />
        </div>
    );
  }
}

The Sketch component will have all your paperjs code, it is a simple Function Component like:

import paper from 'paper';

export default function Sketch() {

   window.onload = function() {
       paper.install(window);
       paper.setup('paper-canvas');

       // draw or call your drawing functions here

       view.onFrame = draw;
   }

   function draw(event) {
       // animation loop
   }

   // Most return null
   return null;
}

This works just fine for me, but I am having issues calling native paperjs mouse events in the Sketch component at the moment. If anyone can help will be much appreciated.

Cheers

// END OF LINE

Bruit answered 29/8, 2019 at 19:25 Comment(1)
Did you ever determine the problem with your mouse events related to this example? Also having issues with mouse events in PaperJS + ReactJS environment.Yahwistic
I
2

Actually I wrote your code completely with some additional coding. Paperjs Mouse events seems to work, but their position is different than where it is clicked. It is approximately 2 times bigger as a Point. When I clicked 50,50 it draws 100,100. I share my code below (updated version of Ricardo Sanchez's Sketch.js):

import paper from "paper";

export default function Sketch() {
  window.onload = function () {
    paper.install(window);
    paper.setup("paper-canvas");
    draw();

    var myPath;

    paper.view.onMouseDown = function(event) {
        myPath = new paper.Path();
        myPath.strokeColor = 'black';
    }
    
    paper.view.onMouseDrag = function(event) {
        myPath.add(event.point);
    }
    
    paper.view.onMouseUp = function(event) {
        var myCircle = new paper.Path.Circle({
            center: event.point,
            radius: 10
        });
        myCircle.strokeColor = 'black';
        myCircle.fillColor = 'white';
    }

    paper.view.draw();
  };

  function draw(event) {
    const path = new paper.Path.Circle({
      center: [80, 50],
      radius: 35,
      fillColor: "red",
    });

    const secondPath = new paper.Path.Circle({
      center: [120, 50],
      radius: 35,
      fillColor: "#00FF00",
    });
  }

  // Most return null
  return null;
}
Isopiestic answered 5/7, 2020 at 14:46 Comment(1)
This 2x bigger problem appears to be triggered due to multiple calls to paper.setup on the same canvas while on a retina display. I'm not sure how to ensure that paper.setup is only called once and to have React leave the component alone.Photon
E
0

Try setting canvas ref to null when component unmounts. For example,

import React, { useRef, useEffect,useState } from 'react';
import draw1 from './draw1';
import paper from 'paper'

const Canvas = props => {
  
  const canvasRef = useRef(null)

  const [setup, setSetup] = useState(false);
  
  
  useEffect(() => {
    const canvas = canvasRef.current;

    if (setup) {
        return
    }

    paper.setup(canvas)
    setSetup(true)

    draw1()

    return () => {

         canvasRef.current = null
    }

  }, []);
  
  return <canvas ref={canvasRef}  className='bg-slate-400 w-9/12 h-4/5'/>
}

export default Canvas;
Excommunicative answered 12/5, 2023 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.