Search code examples
javascripthtmlcssmatter.js

Matter.js Mouse Controls Setup


I'm trying to add mouse controls to the starter Matter.js example of two boxes. I seem to be missing something because it won't work. I just want to be able to move the bodies around with the mouse.

I'm trying to add mouse controls to the starter Matter.js example of two boxes. I seem to be missing something because it won't work. I just want to be able to move the bodies around with the mouse.

'''

<canvas id="canvasM" data-pixel-ratio="2" style="position:relative; z-index:0;"></canvas>
<script>
      // module aliases
  var Engine = Matter.Engine,
      Render = Matter.Render,
      Runner = Matter.Runner,
      Bodies = Matter.Bodies,
      Composite = Matter.Composite;
      World = Matter.World;
  
  var mouse;
  
  // create an engine
  var engine = Engine.create();
    world = engine.world;
  
  var w = window.innerWidth;
  var h = window.innerHeight;
  
  // create two boxes and a ground
  var boxA = Bodies.rectangle(.5*w+30, .7*h, 80, 80);
  var boxB = Bodies.rectangle(.5*w+60, 50, 80, 80);
  var ground = Bodies.rectangle(.5*w-1, .888*h+.05*h-30+1.5, w, .1*h, { isStatic: true });

  // add all of the bodies to the world
  Composite.add(engine.world, 
                [boxA, boxB, ground]);
  

  // create runner
  var runner = Runner.create();

  // run the engine
  Runner.run(runner, engine);
  
  var canvas = document.getElementById('canvasM');
  context = canvas.getContext('2d');
  canvas.width = window.innerWidth-130;
  canvas.height = 0.888*window.innerHeight;


  
  (function render() {
      var bodies = Composite.allBodies(engine.world);

      window.requestAnimationFrame(render);

      context.beginPath();

      for (var i = 0; i < bodies.length; i += 1) {
          var vertices = bodies[i].vertices;

          context.moveTo(vertices[0].x, vertices[0].y);

          for (var j = 1; j < vertices.length; j += 1) {
              context.lineTo(vertices[j].x, vertices[j].y);
          }

          context.lineTo(vertices[0].x, vertices[0].y);
      }

      context.lineWidth = 3;
      context.fill = '#fff';
      context.strokeStyle = '#000';
      context.stroke();
    

  var mouseC = Matter.MouseConstraint;
  mouseC.pixelRatio = 2;
  var canvmouse = Matter.Mouse.create(document.getElementById('canvasM'));
  mouseC = mouseC.create(engine,{
        mouse: canvmouse});

  Composite.add(world, mouseC);

  render.mouse = mouse;
  
  })();
  
  
  
</script>

'''


Solution

  • The following is a fix to my code. See the variable named mouseControl and in particular Matter.Mouse.setScale(canvmouse,{x:2,y:2}); to fix the mouse coordinate scaling. Special thanks to @ggorlen for the focus and informing of the loop redundancy.

    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
    
    <canvas id="canvasM" data-pixel-ratio="2" style="position:relative; z-index:0;"></canvas>
    <script>
          // module aliases
      var Engine = Matter.Engine,
          Render = Matter.Render,
          Runner = Matter.Runner,
          Bodies = Matter.Bodies,
          Composite = Matter.Composite;
          World = Matter.World;
      
      var mouse;
      
      // create an engine
      var engine = Engine.create();
        world = engine.world;
      
      var w = window.innerWidth;
      var h = window.innerHeight;
      
      // create two boxes and a ground
      var boxA = Bodies.rectangle(.5*w+30, .7*h, 80, 80);
      var boxB = Bodies.rectangle(.5*w+60, 50, 80, 80);
      var ground = Bodies.rectangle(.5*w-1, .888*h+.05*h-30+1.5, w, .1*h, { isStatic: true });
    
      // add all of the bodies to the world
      Composite.add(engine.world, 
                    [boxA, boxB, ground]);
      
    
      
      var canvas = document.getElementById('canvasM');
      context = canvas.getContext('2d');
      canvas.width = window.innerWidth-130;
      canvas.height = 0.888*window.innerHeight;
    
    
      
      (function render() {
          var bodies = Composite.allBodies(engine.world);
    
          window.requestAnimationFrame(render);
    
          context.beginPath();
    
          for (var i = 0; i < bodies.length; i += 1) {
              var vertices = bodies[i].vertices;
    
              context.moveTo(vertices[0].x, vertices[0].y);
    
              for (var j = 1; j < vertices.length; j += 1) {
                  context.lineTo(vertices[j].x, vertices[j].y);
              }
    
              context.lineTo(vertices[0].x, vertices[0].y);
          }
    
          context.lineWidth = 3;
          context.fill = '#fff';
          context.strokeStyle = '#000';
          context.stroke();
        
      Matter.Engine.update(engine);
      })();
      
      var mouseC = Matter.MouseConstraint;
      var canvmouse = Matter.Mouse.create(document.getElementById('canvasM'));
      Matter.Mouse.setScale(canvmouse,{x:2,y:2});
    
      mouseControl = mouseC.create(engine,{
            mouse: canvmouse});
    
      Composite.add(world, mouseControl);
    
      render.mouse = mouse;
      
      
    </script>