问题描述
我有一个功能,可以在单击画布内的圆圈时在鼠标按下时添加图像。现在,每次我单击圆圈时,都会添加一个新图像,这不是我想要的。我想要某种切换功能,以便它在第二次点击时删除图像并在第三次添加一个新图像,依此类推。
我现在的函数是这样的:
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;
});
我想如果我检查画布上是否存在 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,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');
部分。
那么检查这个的正确方法是什么?
完整代码:
https://codepen.io/twan2020/pen/MWbmgqE
解决方法
如果您想切换图像可见性,则只需更改其 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 = [];
现在我们已准备好填充画布。
for (let [idx,props] of hotspots.entries()) {
let c = new fabric.Circle(props);
c.class = 'hotspot';
c.name = 'hotspot-' + idx;
canvas.add(c);
}
这段代码没有什么神奇之处,我们只是在将热点圆圈添加到画布之前,向热点圆圈添加了两个属性 class
和 name
。 class
属性将允许我们过滤画布上的对象,以便我们只将 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
用于在将图像添加到画布之前设置图像的 id
。如果数组中存在热点,那么我们会找到带有图像 id
的画布对象并切换 visible
属性。