どういうわけかこれは機能しません...
var paper = Raphael("test", 500, 500);
var testpath = paper.path('M100 100L190 190');
var a = paper.rect(0,0,10,10);
a.attr('fill', 'silver');
a.mousedown( function() {
testpath.animate({x: 400}, 1000);
});
この方法で四角形を移動することはできますが、パスを移動することはできません。その理由と、パスオブジェクトを移動するにはどうすればよいですか。
Raphaelの最新バージョンでは、次のことができます。
var _transformedPath = Raphael.transformPath('M100 100L190 190', 'T400,0');
testpath.animate({path: _transformedPath}, 1000);
これにより、一時オブジェクトをclone
する必要がなくなります。
path
オブジェクトはx
、y
値を取得していないようです。したがって、アニメーションはおそらく実行されますが、何も実行されません。代わりに、パス関数をアニメーション化してみてください。
testpath.animate({path:'M400 100L490 190'},1000);
アニメーションを書くのは少し難しいですが、回転とスケーリングを無料で利用できるという利点があります。
ところで:これは単なる例だと思いますが、上記のコードでは、var testpath
として初期化しないため、testpath
がグローバルスコープに配置されます。
解決しました、Ruduに感謝します!
アニメートする新しいパスを作成する必要があります。 clone()を使用してこれを実行し、そのクローンに変換を適用できます。このような単純な動きでは非常に複雑に見えますが、機能します...
var paper = Raphael("test", 500, 500);
var testpath = paper.path('M100 100L190 190');
var a = paper.rect(0,0,10,10);
a.attr('fill', 'silver');
a.mousedown( function() {
var temp = testpath.clone();
temp.translate(400,0);
testpath.animate({path: temp.attr('path')}, 1000);
temp.remove();
});
TimDogの答えが最善の解決策でした。
さらに、この場合の変換文字列は、すべてのパスポイント/ラインX座標に400ポイントを追加し、すべてのY座標に0ポイントを追加することを意味することを覚えておいてください。
つまり、M100 100L190 190
はM500 100L590 190
に変わります。
したがって、パス要素を別の位置に移動する必要がある場合は、現在の位置と新しい位置の座標の差を計算する必要があります。これを行うには、最初の要素を使用できます。
var newCoordinates = [300, 200],
curPos = testpath.path[0],
newPosX = newCoordinates[0] - curPos[1],
newPosY = newCoordinates[1] - curPos[2];
var _transformedPath = Raphael.transformPath(testpath.path, "T"+newPosX+","+newPosY);
testpath.animate({path: _transformedPath});
これが誰かを助けることを願っています。
上記の回答の最良のものを一般化し、Raphaelパスに単純な.attr({pathXY: [newXPos, newYPos]})
形状の.attr({x: newXPosition})
や.animate({x: newXPosition})
に似た属性を与えるコードを次に示します。
これにより、パス文字列やカスタム計算をハードコーディングせずに、標準的な方法でパスを固定の絶対位置または相対量だけ移動に移動できます。
編集:以下のコードはIE7およびIE8で機能します。これの以前のバージョンは、次の理由でIE8/VMLモードで失敗しました SVGモードでは配列を.attr( 'path')に返しますが、VMLモードでは文字列を.attr( 'path')に返すRaphaelバグ 。
paper
を定義した後、このコード( Raphael customAttribute 、およびヘルパー関数)を追加します。以下のように使用します。
paper.customAttributes.pathXY = function( x,y ) {
// use with .attr({pathXY: [x,y]});
// call element.pathXY() before animating with .animate({pathXY: [x,y]})
var pathArray = Raphael.parsePathString(this.attr('path'));
var transformArray = ['T', x - this.pathXY('x'), y - this.pathXY('y') ];
return {
path: Raphael.transformPath( pathArray, transformArray)
};
};
Raphael.st.pathXY = function(xy) {
// pass 'x' or 'y' to get average x or y pos of set
// pass nothing to initiate set for pathXY animation
// recursive to work for sets, sets of sets, etc
var sum = 0, counter = 0;
this.forEach( function( element ){
var position = ( element.pathXY(xy) );
if(position){
sum += parseFloat(position);
counter++;
}
});
return (sum / counter);
};
Raphael.el.pathXY = function(xy) {
// pass 'x' or 'y' to get x or y pos of element
// pass nothing to initiate element for pathXY animation
// can use in same way for elements and sets alike
if(xy == 'x' || xy == 'y'){ // to get x or y of path
xy = (xy == 'x') ? 1 : 2;
var pathPos = Raphael.parsePathString(this.attr('path'))[0][xy];
return pathPos;
} else { // to initialise a path's pathXY, for animation
this.attr({pathXY: [this.pathXY('x'),this.pathXY('y')]});
}
};
任意のパスまたは セットのセット(デモ)を含むパスのセット で動作します。 Raphaelセットはグループではなく配列であるため、セット内の各アイテムを、セットの中心ではなく、定義された位置に移動することに注意してください。
// moves to x=200, y=300 regardless of previous transformations
path.attr({pathXY: [200,300]});
// moves x only, keeps current y position
path.attr({pathXY: [200,path.pathXY('y')]});
// moves y only, keeps current x position
path.attr({pathXY: [path.pathXY('x'),300]});
Raphaelは、x座標とy座標の両方を同じcustomAttributeで一緒に処理して、一緒にアニメーション化できるようにし、互いに同期を保つ必要があります。
// moves down, right by 10
path.attr({pathXY: [ path.pathXY('x')+10, path.pathXY('y')+10 ]},500);
これはセットでも機能しますが、ラファエルのセットはグループのようではないことを忘れないでください-各オブジェクトはセットの平均位置に対して1つの位置に移動するため、結果が期待どおりにならない場合があります( 例デモ )。
初めてアニメーション化する前に Raphael 2.1.0までのバグ/欠落機能のため、pathXY値を設定する必要があります。これは、アニメーション化する前にすべてのcustomAttributesに数値を指定する必要があるためです(そうでない場合)。 、すべての数値をNaNに変換して何もせず、エラーなしでサイレントに失敗するか、アニメーション化して最終位置に直接ジャンプしません)。
.animate({pathXY: [newX,newY]});
を使用する前に、次のヘルパー関数を実行してください。
somePath.pathXY();
さらに別の方法は、「変換」属性を使用することです。
testpath.animate({transform: "t400,0"}, 1000);
パスを元の位置に対して400px右に移動します。
これは、パスや長方形を含むすべての形状で機能するはずです。
ご了承ください:
「変換」属性の値は、現在の位置ではなく、常に元の位置に基づいています。上のアニメーションの後に下のアニメーションを適用すると、元の位置に戻すのではなく、比較的左に800px移動します。
testpath.animate({transform: "t-400,0"}, 1000);