【发布时间】:2017-08-20 05:34:25
【问题描述】:
我想要达到的目标:
我正在努力实现两个目标:
- 我需要在 SVG 文档中嵌入单行/多行可编辑文本输入字段。
- 这些字段必须具有拖动功能。
使文本字段成为 SVG 一部分的目的是在 SVG 文档缩放时通过编写任何多余的代码来缩放它们。
为了完成这两个任务,我使用了Snap.svg 库。
到目前为止我做了什么:
SVG 有一个foreignObject 元素,它允许我们在 SVG 中嵌入任何 HTML 标记。因此,使用此功能,我在 SVG 中添加了 input 和 textarea 字段。
下面是一个演示:
var s = Snap('#demo');
var defualtWidth = s.attr('width');
var defualtHeight = s.attr('height');
var fobjectSVG = '<foreignObject x="30" y="40" width="240" height="40"><input type="text" class="form-control"placeholder="Some dummy text here..." /></foreignObject>';
s.append(Snap.parse(fobjectSVG));
$('.select-zoom').change(function(event) {
var zoomRatio = $(this).val();
s.attr({
'width': defualtWidth * zoomRatio,
'height': defualtHeight * zoomRatio
});
});
.form-control {
border: 3px solid #000;
padding: 3px 10px;
background: #fff;
display: block;
height: 100%;
width: 100%;
margin: 0;
}
.select-zoom {
position: absolute;
width: 100px;
height: 30px;
right: 40px;
top: 50px;
z-index: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<svg id="demo" width="700" height="550" viewBox="0 0 700 550">
<image x="0" y="0" width="100%" height="550" href="https://i.imgur.com/waDgcnc.jpg" />
</svg>
<select class="select-zoom">
<option value="0.5">50%</option>
<option value="0.75">75%</option>
<option value="1" selected="selected">100%</option>
<option value="1.25">125%</option>
<option value="1.5">150%</option>
<option value="2">200%</option>
<option value="2.5">250%</option>
<option value="5">500%</option>
</select>
添加拖动功能:
Snap.svg 有一个.drag() 函数,它在调用元素时将拖动功能附加到元素。
下面是一个演示:
var s = Snap('#demo');
var rect = s.rect(30, 30, 240, 120).attr({stroke: '#000', 'strokeWidth': 3, fill: '#2ecc40'});
rect.drag();
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<svg id="demo" width="700" height="550" viewBox="0 0 700 550">
<image x="0" y="0" width="100%" height="550" href="https://i.imgur.com/waDgcnc.jpg" />
</svg>
有什么问题?
当我在这个foreignObject 上调用.drag() 函数时,它里面的input / textarea 字段会停止它们的正常行为。似乎他们的默认行为以某种方式被取消了。
下面是问题的演示:
var s = Snap('#demo');
var defualtWidth = s.attr('width');
var defualtHeight = s.attr('height');
var fobjectSVG = '<foreignObject x="30" y="40" width="240" height="40"><input type="text" class="form-control"placeholder="Some dummy text here..." /></foreignObject>';
var fobjectSVG2 = '<foreignObject x="30" y="100" width="240" height="120"><textarea class="form-control" placeholder="Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, "></textarea></foreignObject>';
var field = s.group().append(Snap.parse(fobjectSVG));
var field2 = s.group().append(Snap.parse(fobjectSVG2));
field.drag();
field2.drag();
$('.select-zoom').change(function(event) {
var zoomRatio = $(this).val();
s.attr({
'width': defualtWidth * zoomRatio,
'height': defualtHeight * zoomRatio
});
});
.form-control {
border: 3px solid #000;
padding: 3px 10px;
background: #fff;
display: block;
height: 100%;
width: 100%;
margin: 0;
}
.select-zoom {
position: absolute;
width: 100px;
height: 30px;
right: 40px;
top: 50px;
z-index: 10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<svg id="demo" width="700" height="550" viewBox="0 0 700 550">
<image x="0" y="0" width="100%" height="550" href="https://i.imgur.com/waDgcnc.jpg" />
</svg>
<select class="select-zoom">
<option value="0.5">50%</option>
<option value="0.75">75%</option>
<option value="1" selected="selected">100%</option>
<option value="1.25">125%</option>
<option value="1.5">150%</option>
<option value="2">200%</option>
<option value="2.5">250%</option>
<option value="5">500%</option>
</select>
正如您在上面的演示中看到的那样,字段正在拖动,但我无法像普通输入/文本区域字段那样编辑它们的文本。
问题是什么?
我想启用他们当前以某种方式禁用的默认行为。有人能解释一下为什么会这样吗?我该如何解决这个问题?
欢迎所有解决方案,无论它们属于此库还是其他库。
编辑:
可以禁用文本字段的文本选择,在我的情况下不需要。
注意: IE 浏览器不支持 foreignObject,因此如果您使用 IE,上述示例可能无法正常工作。然而它是 MS Edge 浏览器支持。
【问题讨论】:
-
我认为问题在于 Snaps 拖动有一个 preventDefault 。但是,解决这个问题可能会引入更大的用户界面问题。您希望在单击鼠标时发生什么。您希望它成为拖动的一部分,还是编辑文本区域(而不是拖动的一部分)。其他拖动处理程序可能会有同样的问题,因为这可能是用户设计问题?
-
@Ian 单击一次,用户应该能够编辑字段内的文本。虽然他/她也应该能够拖动该字段。
-
但是要开始文本区域编辑,它是鼠标按下,而不是单击。所以要么 mousedown = textarea 编辑,要么 mousedown = 开始拖动。如果你想拖动 textarea 中的文本会发生什么?也许你可以捏造一些东西,但它可能永远是一个容易引发问题的捏造。
-
@Ian 好的,有没有可能做到这一点?这是我正在从事的项目的要求。我需要以某种方式实现它。如果我编写一些自定义拖动处理程序,您怎么看?
-
如果您可以解释您希望在不与另一个冲突的鼠标按下时发生的逻辑,则可能取决于此。但是感觉项目的需求可能不对。
标签: javascript jquery html svg snap.svg