我想使一个 SVG 元素(路径、矩形或圆)可以被拖动,并同时提供调整大小的手柄。
但与 HTML DOM 不同,不是所有的元素都有左上角的 x,y 坐标和围绕内容的盒子的宽度和高度。这使得制作通用的调整大小或拖动过程不方便。
有没有将每个路径或圆圈绘制在自己的 SVG 对象中以给我一个可操作的盒子的好方法呢?
在 SVG 中,可拖动/可调整大小通常如何实现?
我想使一个 SVG 元素(路径、矩形或圆)可以被拖动,并同时提供调整大小的手柄。
但与 HTML DOM 不同,不是所有的元素都有左上角的 x,y 坐标和围绕内容的盒子的宽度和高度。这使得制作通用的调整大小或拖动过程不方便。
有没有将每个路径或圆圈绘制在自己的 SVG 对象中以给我一个可操作的盒子的好方法呢?
在 SVG 中,可拖动/可调整大小通常如何实现?
注意:对于拖动和调整大小,您需要为某些不同类型的元素制作单独的情况。请查看我稍后提供的示例,该示例处理了椭圆和矩形在同一组函数中的拖动。
要使元素可拖动,您可以使用:
element.drag(move, start, up);
这三个参数是对处理移动(拖动)、开始(鼠标按下)和停止(鼠标松开)的函数的引用。
例如,要制作一个可拖动的圆形(摘自文档):
window.onload = function() {
var R = Raphael("canvas", 500, 500);
var c = R.circle(100, 100, 50).attr({
fill: "hsb(.8, 1, 1)",
stroke: "none",
opacity: .5
});
var start = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.attr({opacity: 1});
},
move = function (dx, dy) {
// move will be called with dx and dy
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
// restoring state
this.attr({opacity: .5});
};
c.drag(move, start, up);
};
在上面的例子中,ox
和oy
属性被添加到元素上以跟踪其位置,这些属性与dx
和dy
结合使用,用于在拖动时更改元素的位置。
一个更复杂的拖放例子以回答这个问题。
要使对象可调整大小,只需为调整大小器创建第二组拖放方法,并根据拖动调整目标元素的height
和width
。
这是一个完整的拖放和可调整大小的盒子的例子:
window.onload = function() {
var R = Raphael("canvas", 500, 500),
c = R.rect(100, 100, 100, 100).attr({
fill: "hsb(.8, 1, 1)",
stroke: "none",
opacity: .5,
cursor: "move"
}),
s = R.rect(180, 180, 20, 20).attr({
fill: "hsb(.8, .5, .5)",
stroke: "none",
opacity: .5
}),
// start, move, and up are the drag functions
start = function () {
// storing original coordinates
this.ox = this.attr("x");
this.oy = this.attr("y");
this.attr({opacity: 1});
this.sizer.ox = this.sizer.attr("x");
this.sizer.oy = this.sizer.attr("y");
this.sizer.attr({opacity: 1});
},
move = function (dx, dy) {
// move will be called with dx and dy
this.attr({x: this.ox + dx, y: this.oy + dy});
this.sizer.attr({x: this.sizer.ox + dx, y: this.sizer.oy + dy});
},
up = function () {
// restoring state
this.attr({opacity: .5});
this.sizer.attr({opacity: .5});
},
rstart = function () {
// storing original coordinates
this.ox = this.attr("x");
this.oy = this.attr("y");
this.box.ow = this.box.attr("width");
this.box.oh = this.box.attr("height");
},
rmove = function (dx, dy) {
// move will be called with dx and dy
this.attr({x: this.ox + dx, y: this.oy + dy});
this.box.attr({width: this.box.ow + dx, height: this.box.oh + dy});
};
// rstart and rmove are the resize functions;
c.drag(move, start, up);
c.sizer = s;
s.drag(rmove, rstart);
s.box = c;
};
包含的事件处理程序(当然,您可以结合.node()
使用更多)和拖放描述位于页面底部文档中。
您只需创建一个 Raphael 画布,然后每个项将成为不同的元素。只需将它们分配给变量以便处理,就像上面的示例中使用 c
引用所创建的圆形元素一样。
回应这里的评论,这是一个简单的可拖放和调整大小的圆形。诀窍在于圆形使用属性 cx
和 cy
进行定位,使用属性 r
进行大小调整。机制基本相同......椭圆可能稍微复杂一些,但再次,这只是与正确属性一起工作的问题。
window.onload = function() {
var R = Raphael("canvas", 500, 500),
c = R.circle(100, 100, 50).attr({
fill: "hsb(.8, 1, 1)",
stroke: "none",
opacity: .5
}),
s = R.circle(125, 125, 15).attr({
fill: "hsb(.8, .5, .5)",
stroke: "none",
opacity: .5
});
var start = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.sizer.ox = this.sizer.attr("cx");
this.sizer.oy = this.sizer.attr("cy")
this.attr({opacity: 1});
this.sizer.attr({opacity: 1});
},
move = function (dx, dy) {
// move will be called with dx and dy
this.attr({cx: this.ox + dx, cy: this.oy + dy});
this.sizer.attr({cx: this.sizer.ox + dx, cy: this.sizer.oy + dy});
},
up = function () {
// restoring state
this.attr({opacity: .5});
this.sizer.attr({opacity: .5});
},
rstart = function() {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.big.or = this.big.attr("r");
},
rmove = function (dx, dy) {
// move will be called with dx and dy
this.attr({cx: this.ox + dy, cy: this.oy + dy});
this.big.attr({r: this.big.or + Math.sqrt(2*dy*dy)});
};
c.drag(move, start, up);
c.sizer = s;
s.drag(rmove, rstart);
s.big = c;
};
cx
和cy
以及半径。这是一个处理拖动矩形和椭圆的示例==>http://jsfiddle.net/vPyjc/(查看“dragger”函数,它使用if`shapes[ind].type =="rect"`来检查形状类型并分别处理每个形状。)------这意味着您实际上必须编写单独的代码来处理拖动和调整椭圆大小(使用半径和中心坐标而不是框)。 - Peter Ajtaicx
,cy
和radius
来绘制圆形。radius
属性可以通过r
访问,您可以使用它来调整圆形的大小,而不是使用矩形框 - 这里有一个快速调整圆形大小的示例:http://jsfiddle.net/EqrQZ/(当然,在更精细的示例中,您会想要添加一个用于调整大小的手柄)- 请注意,我正在使用r
调整圆形大小。-box
只是较大对象的副本,您必须自己创建它...看看代码的最后一行 ==>s.box = c;
- Peter Ajtai