Search code examples
javascripthtml5-canvasfabricjs

Allow mouse events to pass through a Fabrixjs Canvas instance?


It's been a few years since I have used Fabricjs so forgive me if this is a basic question

I am adding a window-sized Canvas element over some button elements which I also want the user to be able to click.

Is there a property in Fabricjs to allow mouse events to pass through to underlying elements? I've been looking through the docs but haven't found anything


Solution

  • You could use document.elementsFromPoint. Click the upper left corner:

    let doc, html, bod, M, I, mobile, S, Q, aC, rC; // for use on other loads
    addEventListener('load', ()=>{
    doc = document; html = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
    mobile = nav.userAgent.match(/Mobi/i) ? true : false;
    S = (selector, within)=>{
      var w = within || doc;
      return w.querySelector(selector);
    }
    Q = (selector, within)=>{
      var w = within || doc;
      return w.querySelectorAll(selector);
    }
    aC = function(){
      const a = [].slice.call(arguments);
      a.shift().classList.add(...a);
      return aC;
    }
    rC = function(){
      const a = [].slice.call(arguments);
      a.shift().classList.remove(...a);
      return rC;
    }
    // can do below on another page except end load
    const canvas = I('canvas'), ctx = canvas.getContext('2d'), test = I('test');
    ctx.fillStyle = '#070'; ctx.fillRect(0, 0, canvas.width, canvas.height);
    test.onclick = ()=>{
      console.log('test worked');
    }
    canvas.onclick = function(e){
      const all = doc.elementsFromPoint(e.clientX, e.clientY);
      for(let q of all){
        switch(q){
          case test:
            test.click();
            break;
        }
      }
    }
    canvas.onmousemove = function(e){
      const all = doc.elementsFromPoint(e.clientX, e.clientY);
      for(let q of all){
        switch(q){
          case test:
            aC(this, 'pointer');
            break;
          case this:
            rC(this, 'pointer');
            break;
        }
      }
    }
    }); // end load
    *{
      box-sizing:border-box;
    }
    html,body{
     padding:0; margin:0;
    }
    html,body,#outer,#canvas{
      width:100%; height:100%;
    }
    #outer{
      position:relative;
    }
    #outer>*{
      position:absolute;
    }
    .pointer{
      cursor:pointer;
    }
    <div id='outer'>
      <input id='test' type='button' value='test' />
      <canvas id='canvas'></canvas>
    </div>

    You can see how you would test for other cases as well, I hope.