SVG 中的可拖动和可调整大小 [英] Draggables and Resizables in SVG

查看:56
本文介绍了SVG 中的可拖动和可调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让一个 svg 元素(路径、矩形或圆形)能够拖动并给它调整大小的句柄.

I want to make an svg element (path, rect, or circle) be able to be draggable and give it resize handles.

但与 HTML DOM 不同的是,并非所有元素都有左上角的 x,y 坐标以及围绕内容的框的宽度和高度.这使得制作通用调整大小或拖动过程变得不方便.

But unlike HTML DOM, not all elements have an upper left hand corner x,y coordinate and a width and height for a box surrounding the content. This makes it inconvenient to make a generic resize or drag procedure.

把每条路径或圆都画在它自己的 svg 对象内来给我一个玩的盒子是个好主意吗?

Is it a good idea to have each path or circle be drawn inside its own svg object to give me a box to play with?

SVG 中通常如何实现可拖动/可调整大小?

How is draggable/resizable typically implemented in SVG?

推荐答案

注意:对于拖动和调整大小,您必须为某些不同类型的元素制作单独的案例.看看 我稍后提供的示例 处理两者的拖动同一组函数中的椭圆和矩形.

Note: For both drag and resize, you'll have to make separate cases for certain different types of elements. Take a look in the example I provide later on that handles the dragging of both ellipses and rectangles in the same set of functions.

要使元素可拖动,请使用:

To make an element dragable you use:

element.drag(move, start, up);

这三个参数是对处理移动(拖动)、开始(鼠标按下)和停止(鼠标向上)的函数的引用.

The three arguments are references to the functions that handle moving (dragging), starting (mouse down), and the stopping (mouseup).

例如制作一个可拖动的圆圈(来自文档):

For example to make a draggable circle (from the documentation):

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);    
};​

jsFiddle 示例


在上面的例子中,oxoy 属性被附加到元素上以跟踪其位置,并且这些属性与 dx 一起使用dy 用于在拖动元素时更改元素的位置.

In the above example, the ox and oy properties are tacked on to the element to keep track of its location, and these properties in conjunction with dx and dy are used to change the location of the element as it's being dragged.

更复杂的拖放回答这个问题.

要使对象可调整大小,您只需为调整器创建第二组拖放方法,并根据拖动调整目标元素 heightwidth调整器.

To make an object resizeable, you would simply create a second set of drag and drop methods for the resizer and just adjust the target elements height and width based on dragging the resizer.

这是我写的一个完整的拖放和可调整大小的框:

Here's a full of one drag and drop and resizeable box I wrote up:

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()) 并且拖放描述位于页面底部 在文档中.

The included event handlers (you can use more of course in conjunction with .node()) and the drag and drop description is at the bottom of the page in the documentation.

您只需制作一张 Raphael 画布,然后每个项目将是不同的元素.只需将它们分配给变量,以便您可以处理它们,就像在上面的示例中一样(c 用于引用创建的圆元素).

You would simply make one Raphael canvas, and then each item would be a different element. Just assign them to variables so you can handle them, like in the example above ( c was used to refer to the created circle element ).

为了回应评论,这里是一个简单的拖放 + 调整大小的圆圈.诀窍是圆圈使用属性cxcy 来定位,使用r 属性来表示大小.机制几乎相同……椭圆会稍微复杂一些,但这只是使用正确属性的问题.

In response to comments here is a simple drag and drop + resize able circle. The trick is that circles use the attributes cx and cy for positioning and r for size. The mechanics are pretty much the same... an ellipse would be slightly more complicate, but again it's just a question of working with the right attributes.

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;
};

这篇关于SVG 中的可拖动和可调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆