【问题标题】:How to show object bounding box when mouse hover objects in Fabricjs?Fabricjs中鼠标悬停对象时如何显示对象边界框?
【发布时间】:2019-10-03 22:44:49
【问题描述】:


当鼠标悬停在像这个视频这样的对象上时,我想显示对象边界框,怎么做?

我正在使用 canvas.on('mouse:over')selectedObj.drawBorders 功能。但是,轮廓框绘制在不正确的位置。而且我不知道当鼠标移出对象时如何清除该轮廓框。

这是我的代码:

$(function() {
		
		var canvasObject = document.getElementById("editorCanvas");

		// set canvas equal size with div
		$(canvasObject).width($("#canvasContainer").width());
		$(canvasObject).height($("#canvasContainer").height());

		var canvas = new fabric.Canvas('editorCanvas', {
			backgroundColor: 'white',
			selectionLineWidth: 2,
			width: $("#canvasContainer").width(),
			height: $("#canvasContainer").height()
		});
		
		canvas.viewportTransform[4] = 20;
    	canvas.viewportTransform[5] = 40;
		
		canvas.on('mouse:over', function(opts) {
			var selectedObj = opts.target;
			if (selectedObj != null) {
				selectedObj.drawBorders(canvas.getContext())
			}
		});
		
		var text = new fabric.Text('hello world', { left: 50, top: 50 });
		canvas.add(text);
		
		setObjectCoords();
		
		function setObjectCoords() {
		  canvas.forEachObject(function(object) {
			object.setCoords();
		  });
		}
		
	});
<style>
  #canvasContainer {
    width: 100%;
    height: 100vh;
    background-color: gray;
  }
</style>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
  
<div id="canvasContainer">
  <canvas id="editorCanvas"></canvas>
</div>

请帮我解决这个问题!
谢谢!

【问题讨论】:

    标签: html5-canvas fabricjs fabricjs2


    【解决方案1】:

    使用方法_renderControls 并在styleOverride 中设置hasControls : false 仅绘制边框。

    演示

    $(function() {
      var canvas = new fabric.Canvas('editorCanvas', {
        backgroundColor: 'white',
        selectionLineWidth: 2,
        width: $("#canvasContainer").width(),
        height: $("#canvasContainer").height()
      });
    
      var text = new fabric.IText('hello world', {
        left: 50,
        top: 50
      });
      canvas.add(text);
      canvas
      text.on('mouseover', function() {
        this._renderControls(this.canvas.contextTop, {
          hasControls: false
        })
      })
      text.on('mousedown', function() {
        this.canvas.clearContext(this.canvas.contextTop);
      })
      text.on('mouseout', function() {
        this.canvas.clearContext(this.canvas.contextTop);
      })
    });
    <style>
      #canvasContainer {
        width: 100%;
        height: 100vh;
        background-color: gray;
      }
    </style>
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
      
    <div id="canvasContainer">
      <canvas id="editorCanvas"></canvas>
    </div>

    【讨论】:

      【解决方案2】:

      这就是我使用纯 Javascript 的方式: 我使用ctx.measureText() 方法测量文本。 函数drawBBox() 正在绘制没有描边的边界框 在画布上移动鼠标时,我检测鼠标的位置,如果鼠标在框内,我调用 ctx.stroke()。

      请阅读我代码中的 cmets。

      我希望你会发现这很有用,虽然我没有使用 fabricjs

      let ctx = editorCanvas.getContext("2d");
      let cw = editorCanvas.width = canvasContainer.clientWidth,cx = cw/2;
      let ch = editorCanvas.height = canvasContainer.clientHeight,cy = ch/2;
      let start = {x:50,y:50}// where the text begin
      
      
      let text = "hello world"; 
      //set some properties of the text
      ctx.fillStyle = "blue";
      ctx.font="2em Verdana";
      ctx.textBaseline="hanging";
      //draw the text
      ctx.fillText(text,start.x,start.y);
      
      let measure = ctx.measureText(text);
      
      function drawBBox(measure){
      // a function to draw the bounding box
      // the box has no stroke yet
        ctx.beginPath();
        ctx.moveTo(start.x,start.y)
        ctx.lineTo(start.x+measure.width,start.y);
        ctx.lineTo(start.x+measure.width,start.y+36);//36 = 2em: the height of the text
        ctx.lineTo(start.x,start.y+36);
        ctx.closePath();
      }
      
      
      
      editorCanvas.addEventListener("mousemove",(evt)=>{
        //clear the canvas
        ctx.clearRect(0,0,cw,ch);
        //get the position of the mouse
        let m = oMousePos(editorCanvas, evt);
        //draw the text
        ctx.fillText(text,start.x,start.y);
        // draw the bounding box with no stroke
        drawBBox(measure);
        
        // if the mouse is inside the bounding box apply the stroke
        if(ctx.isPointInPath(m.x, m.y)){
          ctx.stroke()
        }
      })
      
      
      // a function to detect the mouse position
       function oMousePos(canvas, evt) {
        var ClientRect = canvas.getBoundingClientRect();
      	return {
      	x: Math.round(evt.clientX - ClientRect.left),
      	y: Math.round(evt.clientY - ClientRect.top)
        }
       }
      #canvasContainer {
          width: 100%;
          height: 100vh;
          background-color: gray;
        }
      <div id="canvasContainer">
        <canvas id="editorCanvas"></canvas>
      </div>

      【讨论】:

        【解决方案3】:

        fabricjs@4.5.1

        它对我有用,就像这样:

        // mouse:over draw bound box
        this._canvas.on('mouse:over', (evet) => {
          const { target } = evet;
          if (this._canvas.getActiveObjects().length) {
            // skip group hover
            return;
          }
        
          // skip group hover
          if (target instanceof fabric.Object && !(target instanceof Array)) {
            const bound = target.getBoundingRect();
            const ctx = this._canvas.getContext();
            ctx.strokeStyle = 'red';
            ctx.strokeRect(
              bound.left,
              bound.top,
              bound.width,
              bound.height
            );
          }
        });
        
        // mouse:out remove bound box
        this._canvas.on('mouse:out', (evet) => {
          const { target } = evet;
          if (this._canvas.getActiveObjects().length) {
            return;
          }
        
          // skipp group hover
          if (target instanceof fabric.Object && !(target instanceof Array)) {
             this._canvas.renderAll(); // render all, will clear bounds box drawed by mouse:over
          }
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-19
          • 2021-06-20
          • 2014-02-25
          • 2018-05-25
          • 2017-05-01
          • 1970-01-01
          • 2013-12-03
          • 2012-09-21
          相关资源
          最近更新 更多