如何修改 svg 文本元素的交互区域以匹配其边界框?
how to modify the interaction area of an svg text element to match its bounding box?
当我使用 Snap 创建文本元素时,比如字母 "a",捕获点击事件的周围区域比边界框大得多,比例至少为 10。这意味着如果我创建第二个文本元素 "b",它靠近但在视觉上与 "a" 分开,交互区域有一个大的交叉点,因此哪个元素被点击主要取决于哪个元素在 earlier/later层。
是否可以将交互区域缩小到尽可能接近边界框,这样分层就不会影响触发哪个元素的点击事件?
Here's a jsfiddle example,其中字体大小最初设置为 0.1px,这是我正在使用的数量级。 (交互区域相对于边界框的大小似乎随着字体大小的减小而增加。)请注意,由于 "b" 是在 "a" 之后创建的,因此触发 "a" 的唯一方法是单击几乎在 canvas 的左边缘。我希望做的是有一系列这样的元素,它们之间的间距相似。
var s = Snap("#svg");
var fontsize = 0.1;
var make_text_box = function(string, fontsize, color) {
var text = s.text(0, 0, string);
text.attr({
'font-size': fontsize + 'px'
});
text.click(
function() {
text.attr({
fill: color
});
}
);
var bbx = text.getBBox().x;
var bby = text.getBBox().y;
var bbw = text.getBBox().w;
var bbh = text.getBBox().h;
var strokewidth = fontsize / 10;
var bbox = s.rect(bbx, bby, bbw, bbh)
.attr({
stroke: "black",
strokeWidth: strokewidth,
fill: "none"
});
var text_and_box = s.g(text, bbox);
return {
g: text_and_box,
x: bbx,
y: bby
};
};
var a_box = make_text_box("a", fontsize, "red");
var b_box = make_text_box("b", fontsize, "limegreen");
b_box.g.transform("translate(" + (2 * fontsize) + ", 0)");
s.attr({
viewBox: (a_box.x - 4 * fontsize) + ", " + (a_box.y - 4 * fontsize) + ", " + (30 * fontsize) + ", " + (10 * fontsize)
});
<script src="https://cdn.jsdelivr.net/snap.svg/0.1.0/snap.svg-min.js"></script>
<svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg"></svg>
我觉得您可能需要为此采取一些棘手的解决方法,因为我不知道有什么方法可以满足您的需求。我认为那里有几个错误,或者可能不清楚小字体应该发生什么。不过像罗伯特这样的人可能有更好的主意。
如果将字体大小保持较大,然后缩小元素,您可能会取得更大的成功。所以像...
var fontsize = 10;
var text = s.text(0, 0, string);
text.attr({
'font-size': fontsize + 'px',
'transform': 's0.05'
});
这已经是我所能得到的最小的了,而且仍然能够看到它并点击它。您可能还想尝试一下形状渲染和文本渲染,让它更清晰一些。
当我使用 Snap 创建文本元素时,比如字母 "a",捕获点击事件的周围区域比边界框大得多,比例至少为 10。这意味着如果我创建第二个文本元素 "b",它靠近但在视觉上与 "a" 分开,交互区域有一个大的交叉点,因此哪个元素被点击主要取决于哪个元素在 earlier/later层。
是否可以将交互区域缩小到尽可能接近边界框,这样分层就不会影响触发哪个元素的点击事件?
Here's a jsfiddle example,其中字体大小最初设置为 0.1px,这是我正在使用的数量级。 (交互区域相对于边界框的大小似乎随着字体大小的减小而增加。)请注意,由于 "b" 是在 "a" 之后创建的,因此触发 "a" 的唯一方法是单击几乎在 canvas 的左边缘。我希望做的是有一系列这样的元素,它们之间的间距相似。
var s = Snap("#svg");
var fontsize = 0.1;
var make_text_box = function(string, fontsize, color) {
var text = s.text(0, 0, string);
text.attr({
'font-size': fontsize + 'px'
});
text.click(
function() {
text.attr({
fill: color
});
}
);
var bbx = text.getBBox().x;
var bby = text.getBBox().y;
var bbw = text.getBBox().w;
var bbh = text.getBBox().h;
var strokewidth = fontsize / 10;
var bbox = s.rect(bbx, bby, bbw, bbh)
.attr({
stroke: "black",
strokeWidth: strokewidth,
fill: "none"
});
var text_and_box = s.g(text, bbox);
return {
g: text_and_box,
x: bbx,
y: bby
};
};
var a_box = make_text_box("a", fontsize, "red");
var b_box = make_text_box("b", fontsize, "limegreen");
b_box.g.transform("translate(" + (2 * fontsize) + ", 0)");
s.attr({
viewBox: (a_box.x - 4 * fontsize) + ", " + (a_box.y - 4 * fontsize) + ", " + (30 * fontsize) + ", " + (10 * fontsize)
});
<script src="https://cdn.jsdelivr.net/snap.svg/0.1.0/snap.svg-min.js"></script>
<svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg"></svg>
我觉得您可能需要为此采取一些棘手的解决方法,因为我不知道有什么方法可以满足您的需求。我认为那里有几个错误,或者可能不清楚小字体应该发生什么。不过像罗伯特这样的人可能有更好的主意。
如果将字体大小保持较大,然后缩小元素,您可能会取得更大的成功。所以像...
var fontsize = 10;
var text = s.text(0, 0, string);
text.attr({
'font-size': fontsize + 'px',
'transform': 's0.05'
});
这已经是我所能得到的最小的了,而且仍然能够看到它并点击它。您可能还想尝试一下形状渲染和文本渲染,让它更清晰一些。