在Fabricjs中将鼠标悬停在对象上时如何显示对象边界框?

时间:2019-05-16 15:41:46

标签: html5-canvas fabricjs fabricjs2


当鼠标悬停在此视频等对象上时,我想显示对象边界框,该怎么做?
enter image description here

我正在将 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>

请帮助我解决此问题!
谢谢!

3 个答案:

答案 0 :(得分:3)

使用方法_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>

答案 1 :(得分:1)

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

请阅读我的代码中的注释。

我希望您会发现这很有用,尽管我没有使用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>

答案 2 :(得分:0)

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
  }
});