如何使用 fabricjs 检查 canvas 上是否存在具有特定 id 的对象
How to check if an object with specific id exists on a canvas with fabricjs
我有一个功能,可以在单击 canvas 中的圆圈时在鼠标按下时添加图像。现在,每次我单击圆圈时,都会添加一个新图像,这不是我想要的。我想要某种切换功能,以便它在第二次单击时删除图像并在第三次添加新图像,依此类推。
我现在的功能是这样的:
cirkel1.on('mousedown', ()=>{
var imgURL = 'https://i1.wp.com/nypost.com/wp-content/uploads/sites/2/2020/04/pugs-coronavirus.jpg';
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, {
width: 350,
height: 100,
left: 250,
top: 70,
scaleX: .25,
scaleY: .25
id: 'testimg'
});
canvas.add(pug);
};
pugImg.src = imgURL;
});
我想如果我检查 canvas 上是否存在 pug
对象,我可以将其删除,并且只在不存在 pug
对象时添加一个新对象。
所以我尝试了这个:
cirkel1.on('mousedown', ()=>{
var imgURL = 'https://printzelf.nl/new/assets/images/logo_gewoon.png';
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, {
width: 350,
height: 100,
left: 250,
top: 70,
scaleX: .25,
scaleY: .25
id: 'testimg'
});
canvas.add(pug);
if(pug > 0){
console.log('pug exists');
}else{
console.log('pug doesnt exist');
}
};
pugImg.src = imgURL;
});
但这总是转到这部分 console.log('pug doesnt exist');
即使 canvas 上有多个哈巴狗。
那么正确的检查方法是什么?
完整代码:
如果你想切换图像可见性那么你只需要改变它的布尔值 visible
属性.
我们不会对每个热点圈进行硬编码,而是使用一个可以扩展以在将来添加更多内容的容器。
const hotspots = [
{
top: 140,
left: 230,
radius: 10,
fill: '#009fe3',
id: 'cirkel1',
hoverCursor: 'pointer',
selectable: false,
imgUrl: 'https://i1.wp.com/nypost.com/wp-content/uploads/sites/2/2020/04/pugs-coronavirus.jpg'
}
];
由于单击热点时会加载图像,因此我们需要跟踪已激活的热点。
const loadedImages = [];
现在我们准备填充 canvas。
for (let [idx, props] of hotspots.entries()) {
let c = new fabric.Circle(props);
c.class = 'hotspot';
c.name = 'hotspot-' + idx;
canvas.add(c);
}
这段代码没有什么神奇之处,我们只是在将热点圈添加到 canvas 之前将两个属性 class
和 name
添加到热点圈中。 class
属性 将允许我们过滤 canvas 上的对象,以便我们只将 mousedown
处理程序添加到热点圈。完成此操作后,我们现在可以添加处理程序了。
for (const ho of canvas.getObjects()) {
// check for 'hotspot' class
if (ho.class && ho.class === 'hotspot') {
ho.on('mousedown', () => {
// check if image was previously loaded
if (loadedImages.indexOf(ho.name) < 0) {
// image is not in the array
// so it needs to be loaded
// prepare the image properties
let imgProps = {
width: 850,
height: 800,
left: (ho.left + 30),
top: (ho.top - 30),
scaleX: .25,
scaleY: .25,
id: 'img-' + ho.name
};
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, imgProps);
canvas.add(pug);
};
pugImg.src = ho.imgUrl;
// update the `loadedImages` array
loadedImages.push(ho.name);
} else {
// image was previously loaded
for (const o of canvas.getObjects()) {
// find the correct image on the canvas
if (o.id && o.id === 'img-' + ho.name) {
// toggle the visible property
o.visible = !o.visible;
break;
}
}
}
});
}
}
mousedown
处理程序有两个可能的执行路径。如果以前没有点击过热点,则不会加载图像。我们通过在 loadedImages
数组中搜索热点的 name
属性 的值来确定这一点。如果找不到名称,则加载图像并将名称添加到数组中。热点 name
用于在将图像添加到 canvas 之前设置图像的 id
。如果热点存在于数组中,那么我们找到带有图像 id
的 canvas 对象并切换 visible
属性.
我有一个功能,可以在单击 canvas 中的圆圈时在鼠标按下时添加图像。现在,每次我单击圆圈时,都会添加一个新图像,这不是我想要的。我想要某种切换功能,以便它在第二次单击时删除图像并在第三次添加新图像,依此类推。
我现在的功能是这样的:
cirkel1.on('mousedown', ()=>{
var imgURL = 'https://i1.wp.com/nypost.com/wp-content/uploads/sites/2/2020/04/pugs-coronavirus.jpg';
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, {
width: 350,
height: 100,
left: 250,
top: 70,
scaleX: .25,
scaleY: .25
id: 'testimg'
});
canvas.add(pug);
};
pugImg.src = imgURL;
});
我想如果我检查 canvas 上是否存在 pug
对象,我可以将其删除,并且只在不存在 pug
对象时添加一个新对象。
所以我尝试了这个:
cirkel1.on('mousedown', ()=>{
var imgURL = 'https://printzelf.nl/new/assets/images/logo_gewoon.png';
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, {
width: 350,
height: 100,
left: 250,
top: 70,
scaleX: .25,
scaleY: .25
id: 'testimg'
});
canvas.add(pug);
if(pug > 0){
console.log('pug exists');
}else{
console.log('pug doesnt exist');
}
};
pugImg.src = imgURL;
});
但这总是转到这部分 console.log('pug doesnt exist');
即使 canvas 上有多个哈巴狗。
那么正确的检查方法是什么?
完整代码:
如果你想切换图像可见性那么你只需要改变它的布尔值 visible
属性.
我们不会对每个热点圈进行硬编码,而是使用一个可以扩展以在将来添加更多内容的容器。
const hotspots = [
{
top: 140,
left: 230,
radius: 10,
fill: '#009fe3',
id: 'cirkel1',
hoverCursor: 'pointer',
selectable: false,
imgUrl: 'https://i1.wp.com/nypost.com/wp-content/uploads/sites/2/2020/04/pugs-coronavirus.jpg'
}
];
由于单击热点时会加载图像,因此我们需要跟踪已激活的热点。
const loadedImages = [];
现在我们准备填充 canvas。
for (let [idx, props] of hotspots.entries()) {
let c = new fabric.Circle(props);
c.class = 'hotspot';
c.name = 'hotspot-' + idx;
canvas.add(c);
}
这段代码没有什么神奇之处,我们只是在将热点圈添加到 canvas 之前将两个属性 class
和 name
添加到热点圈中。 class
属性 将允许我们过滤 canvas 上的对象,以便我们只将 mousedown
处理程序添加到热点圈。完成此操作后,我们现在可以添加处理程序了。
for (const ho of canvas.getObjects()) {
// check for 'hotspot' class
if (ho.class && ho.class === 'hotspot') {
ho.on('mousedown', () => {
// check if image was previously loaded
if (loadedImages.indexOf(ho.name) < 0) {
// image is not in the array
// so it needs to be loaded
// prepare the image properties
let imgProps = {
width: 850,
height: 800,
left: (ho.left + 30),
top: (ho.top - 30),
scaleX: .25,
scaleY: .25,
id: 'img-' + ho.name
};
var pugImg = new Image();
pugImg.onload = function (img) {
var pug = new fabric.Image(pugImg, imgProps);
canvas.add(pug);
};
pugImg.src = ho.imgUrl;
// update the `loadedImages` array
loadedImages.push(ho.name);
} else {
// image was previously loaded
for (const o of canvas.getObjects()) {
// find the correct image on the canvas
if (o.id && o.id === 'img-' + ho.name) {
// toggle the visible property
o.visible = !o.visible;
break;
}
}
}
});
}
}
mousedown
处理程序有两个可能的执行路径。如果以前没有点击过热点,则不会加载图像。我们通过在 loadedImages
数组中搜索热点的 name
属性 的值来确定这一点。如果找不到名称,则加载图像并将名称添加到数组中。热点 name
用于在将图像添加到 canvas 之前设置图像的 id
。如果热点存在于数组中,那么我们找到带有图像 id
的 canvas 对象并切换 visible
属性.