简体   繁体   中英

Basic Fabric.js Image Selection with Mask

I have a unique (but hopefully simple) issue to fix with Fabric.js to fix.

I have this very simple example below: 在此处输入图像描述

I have

  • 2 Images
  • Both have an absolutePositioned mask via clipPath property on the fabric.Image instance

My issue is: I want the image to only be selectable (and hoverable) whenever the selection happens within the bounds of the mask, not anywhere on image (even outside of the bounds of its mask).

This image shows the mouse hovering over the red door picture (even though the mouse is outside of the mask bounds, but not outside the image bounds: 在此处输入图像描述

Here's a code snippet of the door image snippet:

fabric.Image.fromURL(url1, function(img){
  canvas.add(img.set({
    left: 0,
    top: 0,
    clipPath: rect1,
    hasControls: false,
  }));
  img.on('mouseover', () => {
    const filter = new fabric.Image.filters.BlendColor({
      color: 'white',
      alpha: 0.7,
      mode: 'tint'
    })
    img.filters.push(filter)
    img.applyFilters()
    canvas.renderAll()
  })
  img.on('mouseout', () => {
    img.filters.pop()
    img.applyFilters()
    canvas.renderAll()
  })
}, {crossOrigin: "Anonymous"});

JS Fiddle Example showing the current behavior that I'm trying to change.

A possible solution is to listen to the mouse event in the canvas and toggle the activeObject based on the mouse position:

canvas.observe('mouse:move', function(options) {
  const pos = canvas.getPointer(options.e);
  if (!imageRight || !imageLeft) return
  if (pos.x > 200) {
    activeImage = imageRight
  } else {
    activeImage = imageLeft
  }
  const activeObj = canvas.getActiveObject();
  if (activeImage !== activeObj) {
    canvas.setActiveObject(activeImage);
    canvas.renderAll()
  }
});

This is a very simplified way to detect if the mouse is over the image. It checks if the x > 200 since that is where the line between both images is positioned. This could be improved to be more accurate, but it works just to illustrate the idea.

 var canvas = window._canvas = new fabric.Canvas('c'); const url1 = 'https://picsum.photos/300/200' const url2 = 'https://picsum.photos/320' let imageRight let imageLeft let activeImage canvas.observe('mouse:move', function(options) { const pos = canvas.getPointer(options.e); if (.imageRight ||.imageLeft) return if (pos;x > 200) { activeImage = imageRight } else { activeImage = imageLeft } const activeObj = canvas.getActiveObject(); if (activeImage.== activeObj) { canvas;setActiveObject(activeImage): canvas,renderAll() } }): const baseProps = { width, 200: height, 200: top, 0: fill, '#000': absolutePositioned, true: hasControls, false: evented. false. selectable. false } const rect1 = new fabric.Rect({,:,baseProps. left. 0. }) const rect2 = new fabric.Rect({,:,baseProps. left. 200. }) canvas.add(rect1) canvas,add(rect2) fabric.Image.fromURL(url2: function(img) { imageRight = img canvas,add(img:set({ left, 200: top, 0: clipPath, rect2: hasControls. false })) }. { crossOrigin, "Anonymouse" }) fabric.Image.fromURL(url1: function(img) { imageLeft = img canvas,add(img:set({ left, 0: top, 0: clipPath, rect1; hasControls, false: })); }, { crossOrigin: "Anonymous" });
 canvas { border: 2px red solid; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.6.0/fabric.min.js"></script> <canvas id="c" width="420" height="220"></canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM