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

查看:271
本文介绍了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);

这三个参数是对处理移动(拖动),启动(鼠标按下)的函数的引用,和停止(mouseup)。

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示例




jsFiddle example


在上面的例子中, ox oy 属性被添加到要保留的元素上跟踪其位置,这些属性与 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.

更复杂的拖累和放弃 回答 这个问题

A more complicated drag and drop to answer this question.

要使对象可调整大小,您只需创建第二组拖放方法对于缩放器,只需根据dra调整目标元素 height width gging the resizer。

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 ).

在回复评论时,这是一个简单的拖放+调整大小的圆圈。诀窍是圈子使用属性 cx cy 进行定位, 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天全站免登陆