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

How to reinitlize canvas, resize body ,element ? #1317

Open
anhtuanlee opened this issue Sep 12, 2024 · 0 comments
Open

How to reinitlize canvas, resize body ,element ? #1317

anhtuanlee opened this issue Sep 12, 2024 · 0 comments

Comments

@anhtuanlee
Copy link

anhtuanlee commented Sep 12, 2024

I'm newbie matterjs, was create element, but i want reponsive element when resize. I defended myself by reloading the page.

Here my code init

class MatterLogos {
  widthCanvas = document.body.clientWidth;
  heightCanvas: number;
  DOM: { el: HTMLElement };
  dataImgs: string[] = [];
  MatterJS: {
    Engine?: () => Engine;
    Render?: () => Render;
  };
  sizeCustom: {
    mobile: { [key: string]: number };
    desktop: { [key: string]: number };
    tablet: { [key: string]: number };
  };

  constructor(element: HTMLElement) {
    this.DOM = { el: element };
    this.MatterJS = { Engine: undefined, Render: undefined };
    this.sizeCustom = {
      mobile: {
        radius: convertRemToPx(5),
        scaleRatio: convertRemToPx(5) / 133,
        scaleCircleMain: 171 / 50,
        xLeftWall: 0 - convertRemToPx(9),
        xRightWall: window.innerWidth + convertRemToPx(9),
        yMainCircle: convertRemToPx(72.2) + convertRemToPx(17),
      },
      tablet: {
        radius: convertRemToPx(5),
        scaleRatio: convertRemToPx(5) / 133,
        scaleCircleMain: 190 / 50,
        xLeftWall: 0 - convertRemToPx(9),
        xRightWall: window.innerWidth + convertRemToPx(9),
        yMainCircle: convertRemToPx(72.2) + convertRemToPx(19),
      },
      desktop: {
        radius: convertRemToPx(13.3),
        scaleRatio: convertRemToPx(13.3) / 133,
        scaleCircleMain: 293 / 133,
        xLeftWall: 0,
        xRightWall: window.innerWidth,
        yMainCircle: convertRemToPx(51.2) + convertRemToPx(29.3),
      },
    };
    this.heightCanvas = this.DOM.el.clientHeight as number;

    element?.querySelectorAll('.home-bubble-item').forEach((item) => {
      const src = item.querySelector('img')?.getAttribute('src');
      if (src) {
        this.dataImgs.push(src);
      }
      (item as HTMLElement).style.pointerEvents = 'none';
      (item as HTMLElement).style.opacity = '0';
    });
  }

  render(): void {
    this.init();

    const runner = Matter.Runner.create();
    const engine = this.MatterJS.Engine?.();
    const render = this.MatterJS.Render?.();

    ScrollTrigger.create({
      trigger: this.DOM.el,
      start: 'top top',
      end: 'bottom center',
      onEnter: (): void => {
        if (!engine || !render) return;
        Matter.Render.run(render);
        Matter.Runner.run(runner, engine);
      },
    });
  }

  init(): void {
    const radius = this.sizeCustom[isSizeCurrent].radius;
    const scaleRatio = this.sizeCustom[isSizeCurrent].scaleRatio;
    const scaleCircleMain = this.sizeCustom[isSizeCurrent].scaleCircleMain;
    const xLeftWall = this.sizeCustom[isSizeCurrent].xLeftWall;
    const xRightWall = this.sizeCustom[isSizeCurrent].xRightWall;
    const yMainCircle = this.sizeCustom[isSizeCurrent].yMainCircle;

    const engine = Matter.Engine.create();
    const render = Matter.Render.create({
      element: this.DOM.el,
      engine: engine,
      options: {
        width: this.widthCanvas,
        height: this.heightCanvas,
        background: 'transparent',
        wireframes: false,
        showAngleIndicator: false,
      },
    });
    const handleCalPosition = (i: number): { x: number; y: number } => {
      const yOver = convertRemToPx(10);

      if (i * radius < window.innerWidth) {
        return { x: i * radius, y: -yOver };
      } else {
        const y = -Math.ceil((i * radius) / window.innerWidth) * yOver * 2;
        return { x: Math.abs(window.innerWidth - radius * i), y };
      }
    };
    for (let i = 0; i < this.dataImgs.length; i++) {
      const { x, y } = handleCalPosition(i);
      const circle = Bodies.circle(x, y, radius, {
        restitution: 0,
        friction: 0.1,
        frictionAir: 0,
        timeScale: 1.5,
        render: {
          fillStyle: '#f3f3f3',
          visible: true,
          sprite: {
            texture: this.dataImgs[i],
            xScale: scaleRatio,
            yScale: scaleRatio,
          },
        },
      });
      Matter.Composite.add(engine.world, circle);
    }

    const mainCircle = Bodies.circle(
      this.DOM.el.clientWidth / 2,
      yMainCircle,
      radius * scaleCircleMain,
      {
        render: { fillStyle: 'transparent' },
        isStatic: true,
      }
    );

    const ground = Bodies.rectangle(
      this.DOM.el.clientWidth / 2,
      this.DOM.el.clientHeight,
      this.DOM.el.clientWidth * 10,
      1,
      {
        isStatic: true,
        render: { fillStyle: 'transparent' },
      }
    );

    const leftWall = Bodies.rectangle(
      xLeftWall,
      this.DOM.el.clientHeight / 2,
      1,
      this.DOM.el.clientHeight * 5,
      {
        isStatic: true,
        render: { fillStyle: 'transparent' },
      }
    );

    const rightWall = Bodies.rectangle(
      xRightWall,
      this.DOM.el.clientHeight / 2,
      1,
      this.DOM.el.clientHeight * 5,
      {
        isStatic: true,
        render: { fillStyle: 'transparent' },
      }
    );

    Matter.Composite.add(engine.world, [ground, leftWall, rightWall, mainCircle]);

    const mouse = Matter.Mouse.create(render.canvas);
    const mouseConstraint = Matter.MouseConstraint.create(engine, {
      mouse: mouse,
      constraint: {
        stiffness: 0.2,
        render: { visible: false },
      },
    });

    Matter.Composite.add(engine.world, mouseConstraint);

    // Remove default mouse wheel event listeners
    //@ts-ignore havent type in framework
    // mouse.element.removeEventListener('wheel', mouse.mousewheel);
    //@ts-ignore havent type in framework
    // mouse.element.removeEventListener('DOMMouseScroll', mouse.mousewheel);

    mouseConstraint.mouse.element.removeEventListener(
      'touchstart',
      //@ts-ignore havent type in framework

      mouseConstraint.mouse.mousedown
    );
    mouseConstraint.mouse.element.removeEventListener(
      'touchmove',
      //@ts-ignore havent type in framework
      mouseConstraint.mouse.mousemove
    );
    mouseConstraint.mouse.element.removeEventListener(
      'touchend',
      //@ts-ignore havent type in framework
      mouseConstraint.mouse.mouseup
    );

    mouseConstraint.mouse.element.addEventListener(
      'touchstart',
      //@ts-ignore havent type in framework
      mouseConstraint.mouse.mousedown,
      {
        passive: true,
      }
    );
    mouseConstraint.mouse.element.addEventListener('touchmove', (e) => {
      if (mouseConstraint.body) {
        //@ts-ignore havent type in framework
        mouseConstraint.mouse.mousemove(e);
      }
    });
    mouseConstraint.mouse.element.addEventListener('touchend', (e) => {
      if (mouseConstraint.body) {
        //@ts-ignore havent type in framework
        mouseConstraint.mouse.mouseup(e);
      }
    });

    this.MatterJS.Render = (): Render => render;
    this.MatterJS.Engine = (): Engine => engine;
  }
}

How i can reinit when resize, tks!

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