Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Please include examples about Custom Components using High Order Components #460

Open
jdnichollsc opened this issue Oct 12, 2023 · 0 comments

Comments

@jdnichollsc
Copy link

jdnichollsc commented Oct 12, 2023

Description

Hello folks, hope you're doing!

This lib is amazing, thanks for sharing this project with the community!

About my request, it would be great to include examples in the docs/website about using High Order Components while creating custom components, please check my below example and let me know what you think! <3

  • src/hocs/withPixiDraggable.tsx
import { _ReactPixi } from '@pixi/react';
import { useRef, type ComponentType, useState } from 'react';
import { FederatedPointerEvent } from 'pixi.js';

let index = 1;
export function withPixiDraggable<T extends _ReactPixi.IContainer>(
  WrappedComponent: ComponentType<T>
): ComponentType<T> {
  return function (props) {
    const containerRef = useRef<T>();
    const isDragging = useRef(false);
    const offset = useRef({ x: 0, y: 0 });
    const [position, setPosition] = useState({
      x: props.x || (props.position ? props.position[0] : 0) || 0,
      y: props.y || (props.position ? props.position[1] : 0) || 0,
    });
    const [alpha, setAlpha] = useState(1);
    const [zIndex, setZIndex] = useState(index);

    function onStart(e: FederatedPointerEvent) {
      isDragging.current = true;
      offset.current = {
        x: e.data.global.x - position.x,
        y: e.data.global.y - position.y,
      };

      setAlpha(0.5);
      setZIndex(index++);
    }

    function onEnd() {
      isDragging.current = false;
      setAlpha(1);
    }

    function onMove(e: FederatedPointerEvent) {
      if (isDragging.current) {
        setPosition({
          x: e.data.global.x - offset.current.x,
          y: e.data.global.y - offset.current.y,
        });
      }
    }
    return (
      <WrappedComponent
        {...(props as T)}
        ref={containerRef}
        alpha={alpha}
        position={position}
        zIndex={zIndex}
        eventMode='static'
        cursor='pointer'
        pointerdown={onStart}
        pointerup={onEnd}
        pointerupoutside={onEnd}
        pointermove={onMove}
      />
    );
  };
}

Then you can use this new component to extend Pixi React components, e.g:

  • src/App.tsx
import { Sprite } from '@pixi/react';
import { withPixiDraggable } from './hocs/withPixiDraggable';

export const DraggableSprite = withPixiDraggable(Sprite);

export const App: React.FC = () => {
  return (
    <Stage>
      <DraggableSprite
        image="..."
        width={250}
        height={250}
      />
    </Stage>
  );
};

export default App;

Wondering if you can include HOCs like this from this project, any feedback is really appreciated! <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant