如何在 Fabricjs 中鼠标悬停对象时显示对象边界框?
How to show object bounding box when mouse hover objects in Fabricjs?
当鼠标悬停在像这个视频这样的对象上时,我想显示对象边界框,该怎么做?
我正在使用 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>
请帮我解决这个问题!
谢谢!
这就是我使用普通 Javascript 的方式:
我使用 ctx.measureText()
方法测量文本。
函数 drawBBox()
正在绘制没有描边的边界框
在 canvas 上移动鼠标时,我检测到鼠标的位置,如果鼠标在框内,我调用 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>
使用方法 _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>
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
}
});
当鼠标悬停在像这个视频这样的对象上时,我想显示对象边界框,该怎么做?
我正在使用 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>
请帮我解决这个问题!
谢谢!
这就是我使用普通 Javascript 的方式:
我使用 ctx.measureText()
方法测量文本。
函数 drawBBox()
正在绘制没有描边的边界框
在 canvas 上移动鼠标时,我检测到鼠标的位置,如果鼠标在框内,我调用 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>
使用方法 _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>
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
}
});