長い質問で申し訳ありませんが、ここに行きます。私はここでデモの周りのドラッグ形状を変更しようとしています:
http://raphaeljs.com/graffle.html
デモは正常に動作します。私がやりたいのは、単語を図形の中に入れ、図形とテキストを単一の複合オブジェクトとして移動することです。
オブジェクトを作成するためのコードは次のとおりです。
window.onload = function () {
var dragger = function () {
this.ox = this.type == "rect" ? this.attr("x") : this.attr("cx");
this.oy = this.type == "rect" ? this.attr("y") : this.attr("cy");
this.animate({"fill-opacity": .2}, 500);
},
move = function (dx, dy) {
var att = this.type == "rect" ? {x: this.ox + dx, y: this.oy + dy} : {cx: this.ox + dx, cy: this.oy + dy};
this.attr(att);
for (var i = connections.length; i--;) {
r.connection(connections[i]);
}
r.safari();
},
up = function () {
this.animate({"fill-opacity": 0}, 500);
},
r = Raphael("holder", 640, 480),
connections = [],
shapes = [ r.ellipse(190, 100, 30, 20),
r.rect(290, 80, 60, 40, 10),
r.rect(290, 180, 60, 40, 2),
r.ellipse(450, 100, 20, 20)
];
for (var i = 0, ii = shapes.length; i < ii; i++) {
var color = Raphael.getColor();
shapes[i].attr({fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move"});
shapes[i].drag(move, dragger, up);
}
connections.Push(r.connection(shapes[0], shapes[1], "#fff"));
connections.Push(r.connection(shapes[1], shapes[2], "#fff", "#fff|5"));
connections.Push(r.connection(shapes[1], shapes[3], "#000", "#fff"));
};
私はこのようなものを試しました:
myWords = [ r.text(190, 100, "Hello"),
r.text(480,100, "Good Bye")
];
それが機能するように他の場所で調整を行いましたが、テキストと形状を移動するだけで、形状とテキストが全体として表示されることはありません。テキストを図形から分離したり、その逆を行ったりできます。それらを1つのオブジェクトにする必要があります。一緒に移動します。どうやってやるの?助けてくれてありがとう.
編集:
私はこれを試しました:
st.Push(r.text (190, 100, "node1"), r.ellipse(190, 100, 30, 20)),
st.Push(r.text (290, 80, "Center"), r.rect(290, 80, 60, 40, 10)),
st.Push(r.text (290, 180, "node2"), r.rect(290, 180, 60, 40, 2)),
st.Push(r.text (450, 100, "node3"), r.ellipse(450, 100, 20, 20))
ただし、図形を移動すると、テキストと図形が一緒に表示されません。テキストはそのまま残りました。
編集: http://raphaeljs.com/graffle.html でストックデモを取得できず、Chromeで動作しません。 IE動作します。
大幅に編集して、要素をよりエレガントな方法で関連付けました。
SetsはRaphaelオブジェクトをグループ化するのに適していますが、セットは独自の要素を作成しないため、ドラッグできませんそして、セットをドロップします。キャンバスをクリックすると、形状またはテキストのいずれかを選択しますが、セットは選択しません(セット要素がないため)。
これは、セットのプロパティを示す簡単なjsFiddleです。セットにはx
またはy
プロパティ。
[セットc]は、配列のようなオブジェクトを作成して、いくつかの要素を同時に保持および操作します。 警告:ページ内にそれ自体の要素は作成されません。
簡単な回避策は、テキストと図形の両方を個別にドラッグ可能にすることです。次に、関連付けられているテキストを図形と一緒に移動します...関連する図形をテキストと一緒に移動します。
このようなオブジェクトの関連付けは簡単です...プロパティを作成します。この場合、各図形と各テキストには、関連する要素への参照である_.pair
_というプロパティがあります。
方法は次のとおりです。
_var i, ii, tempS, tempT
shapes = [ ... ],
texts = [ ... ];
for (i = 0, ii = shapes.length; i < ii; i++) {
tempS = shapes[i].attr( ... );
tempT = texts[i].attr( ...);
// Make all the shapes and texts dragable
shapes[i].drag(move, dragger, up);
texts[i].drag(move, dragger, up);
// Associate the elements
tempS.pair = tempT;
tempT.pair = tempS;
}
_
次に、ドラッグアンドドロップコードで、move()
、dragger()
、およびup()
関数を使用して、クリックされた要素の両方を処理する必要があります。とその関連要素。
たとえば、以下はmove()
関数の関連部分です。 text
はrectangle
と同じ方法で(属性x
とy
を変更することで)処理できるため、false
以下の各Javascript条件演算子の条件は、rectangle
とtext
の両方のケースを処理します
_move = function (dx, dy) {
// Move main element
var att = this.type == "ellipse" ?
{cx: this.ox + dx, cy: this.oy + dy} :
{x: this.ox + dx, y: this.oy + dy};
this.attr(att);
// Move paired element
att = this.pair.type == "ellipse" ?
{cx: this.pair.ox + dx, cy: this.pair.oy + dy} :
{x: this.pair.ox + dx, y: this.pair.oy + dy};
this.pair.attr(att);
...
}
_
そして、以下は完全に機能するコードです:
_Raphael.fn.connection = function (obj1, obj2, line, bg) {
if (obj1.line && obj1.from && obj1.to) {
line = obj1;
obj1 = line.from;
obj2 = line.to;
}
var bb1 = obj1.getBBox(),
bb2 = obj2.getBBox(),
p = [{x: bb1.x + bb1.width / 2, y: bb1.y - 1},
{x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1},
{x: bb1.x - 1, y: bb1.y + bb1.height / 2},
{x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2},
{x: bb2.x + bb2.width / 2, y: bb2.y - 1},
{x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1},
{x: bb2.x - 1, y: bb2.y + bb2.height / 2},
{x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2}],
d = {}, dis = [];
for (var i = 0; i < 4; i++) {
for (var j = 4; j < 8; j++) {
var dx = Math.abs(p[i].x - p[j].x),
dy = Math.abs(p[i].y - p[j].y);
if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) {
dis.Push(dx + dy);
d[dis[dis.length - 1]] = [i, j];
}
}
}
if (dis.length == 0) {
var res = [0, 4];
} else {
res = d[Math.min.apply(Math, dis)];
}
var x1 = p[res[0]].x,
y1 = p[res[0]].y,
x4 = p[res[1]].x,
y4 = p[res[1]].y;
dx = Math.max(Math.abs(x1 - x4) / 2, 10);
dy = Math.max(Math.abs(y1 - y4) / 2, 10);
var x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3),
y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3),
x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3),
y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3);
var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(",");
if (line && line.line) {
line.bg && line.bg.attr({path: path});
line.line.attr({path: path});
} else {
var color = typeof line == "string" ? line : "#000";
return {
bg: bg && bg.split && this.path(path).attr({stroke: bg.split("|")[0], fill: "none", "stroke-width": bg.split("|")[1] || 3}),
line: this.path(path).attr({stroke: color, fill: "none"}),
from: obj1,
to: obj2
};
}
};
var el;
window.onload = function () {
var color, i, ii, tempS, tempT,
dragger = function () {
// Original coords for main element
this.ox = this.type == "ellipse" ? this.attr("cx") : this.attr("x");
this.oy = this.type == "ellipse" ? this.attr("cy") : this.attr("y");
if (this.type != "text") this.animate({"fill-opacity": .2}, 500);
// Original coords for pair element
this.pair.ox = this.pair.type == "ellipse" ? this.pair.attr("cx") : this.pair.attr("x");
this.pair.oy = this.pair.type == "ellipse" ? this.pair.attr("cy") : this.pair.attr("y");
if (this.pair.type != "text") this.pair.animate({"fill-opacity": .2}, 500);
},
move = function (dx, dy) {
// Move main element
var att = this.type == "ellipse" ? {cx: this.ox + dx, cy: this.oy + dy} :
{x: this.ox + dx, y: this.oy + dy};
this.attr(att);
// Move paired element
att = this.pair.type == "ellipse" ? {cx: this.pair.ox + dx, cy: this.pair.oy + dy} :
{x: this.pair.ox + dx, y: this.pair.oy + dy};
this.pair.attr(att);
// Move connections
for (i = connections.length; i--;) {
r.connection(connections[i]);
}
r.safari();
},
up = function () {
// Fade original element on mouse up
if (this.type != "text") this.animate({"fill-opacity": 0}, 500);
// Fade paired element on mouse up
if (this.pair.type != "text") this.pair.animate({"fill-opacity": 0}, 500);
},
r = Raphael("holder", 640, 480),
connections = [],
shapes = [ r.ellipse(190, 100, 30, 20),
r.rect(290, 80, 60, 40, 10),
r.rect(290, 180, 60, 40, 2),
r.ellipse(450, 100, 20, 20)
],
texts = [ r.text(190, 100, "One"),
r.text(320, 100, "Two"),
r.text(320, 200, "Three"),
r.text(450, 100, "Four")
];
for (i = 0, ii = shapes.length; i < ii; i++) {
color = Raphael.getColor();
tempS = shapes[i].attr({fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move"});
tempT = texts[i].attr({fill: color, stroke: "none", "font-size": 15, cursor: "move"});
shapes[i].drag(move, dragger, up);
texts[i].drag(move, dragger, up);
// Associate the elements
tempS.pair = tempT;
tempT.pair = tempS;
}
connections.Push(r.connection(shapes[0], shapes[1], "#fff"));
connections.Push(r.connection(shapes[1], shapes[2], "#fff", "#fff|5"));
connections.Push(r.connection(shapes[1], shapes[3], "#000", "#fff"));
};
_
完全を期すために、のコードは、setのプロパティを表示するためにjsFiddleにリンクされています。
_window.onload = function () {
var paper = Raphael("canvas", 320, 200),
st = paper.set(),
propArr = [];
st.Push(
paper.circle(10, 10, 5),
paper.circle(30, 10, 5)
);
st.attr({fill: "red"});
for(var prop in st) {
if (st.hasOwnProperty(prop)) {
// handle prop as required
propArr.Push(prop + " : " + st[prop]);
}
}
alert(propArr.join("\n"));
};
// Output:
// 0 : Raphael's object
// 1 : Raphael's object
// items : Raphael's object,Raphael's object
// length : 2
// type : set
_
または、適切なSVGグループ要素を作成できるRaphaelのこの「グループ」プラグインを試してください。
https://github.com/rhyolight/Raphael-Plugins/blob/master/raphael.group.js
はい、それがset
オブジェクトの目的です。
var myWords = r.set();
myWords.Push(
r.text(190, 100, "Hello"),
r.text(480,100, "Good Bye"
);
// now you can treat the set as a single object:
myWords.rotate(90);
追加回答:
OK、私はあなたがsetを使用しようとしたが、それを間違って使用しているようです。セットは物事のグループを作成します。 Adobe Illustrator、Inkscape、Microsoft Word、またはOpen Officeで図形やテキストをグループ化する場合と同じです。私があなたを正しく理解しているなら、あなたが望むものはこれです:
shapes = [ r.set(r.text (190, 100, "node1"), r.ellipse(190, 100, 30, 20)),
r.set(r.text (290, 80, "Center"), r.rect(290, 80, 60, 40, 10)),
r.set(r.text (290, 180, "node2"), r.rect(290, 180, 60, 40, 2)),
r.set(r.text (450, 100, "node3"), r.ellipse(450, 100, 20, 20))
];
また、形状は「rect」タイプではなく「set」タイプであるため、ドラッガと移動関数を変更する必要があります。
var dragger = function () {
this.ox = this.attr("x");
this.oy = this.attr("y");
this.animate({"fill-opacity": .2}, 500);
};
var move = function (dx, dy) {
var att = {x: this.ox + dx, y: this.oy + dy};
this.attr(att);
for (var i = connections.length; i--;) {
r.connection(connections[i]);
}
r.safari();
};
すべてのセットにはx
およびy
属性があります。
メインオブジェクトがドラッグされたときに変化する属性に加えて、ペアのオブジェクトの属性を変更する方が簡単ではないでしょうか。
このようなもの:
window.onload = function () {
var R = Raphael("holder"),
circ = R.circle(100, 100, 50).attr({ "fill": "#d9d9d9", "stroke-width": 1 }),
circ2 = R.circle(50, 50, 5),
start = function () {
this.ox = this.attr("cx"); //ox = original x value
this.oy = this.attr("cy");
this.animate({ "opacity": .5, "stroke-width": 15 }, 200);
},
move = function (dx, dy) { //dx - delta x - diiference in movement between point a and b
var cdx = circ2.attr("cx") - this.attr("cx"),
cdy = circ2.attr("cy") - this.attr("cy");
this.attr({ "cx": this.ox + dx, "cy": this.oy + dy });
group(this,circ2,cdx,cdy);
R.safari();
},
up = function () {
this.animate({ "opacity": 1, "stroke-width": 1 }, 200);
},
group = function (refObj,thisObj, dx, dy) {
thisObj.attr({ "cx": refObj.attr("cx") + dx, "cy": refObj.attr("cy") + dy });
};
circ.drag(move, start, up);
};