Javascriptを使用して、SVGドキュメント内の特定の要素のサイズを変更して回転する必要があります。問題は、デフォルトでは、(0, 0)
–左上のOriginの周りに常に変換を適用することです。
この変換アンカーポイントを再定義するにはどうすればよいですか?
transform-Origin
属性を使用してみましたが、何の影響もありません。
これは私がそれをやった方法です:
svg.getDocumentById('someId').setAttribute('transform-Origin', '75 240');
Firefoxで属性が正しく設定されていることがわかりますが、ピボットポイントは指定したポイントに設定されていないようです。 center bottom
や50% 100%
のようなものをかっこありとなしで試しました。今のところ何も機能していません。
誰でも助けることができますか?
回転するにはtransform="rotate(deg, cx, cy)"
を使用します。ここで、degは回転する角度で、(cx、cy)は回転の中心を定義します。
スケーリング/サイズ変更を行うには、(-cx、-cy)で変換し、スケーリングしてから(cx、cy)に戻す必要があります。 マトリックス変換 でこれを行うことができます:
transform="matrix(sx, 0, 0, sy, cx-sx*cx, cy-sy*cy)"
ここで、sxはx軸の倍率、syはy軸の倍率です。
固定値(「center」または「50%」ではない)を使用できる場合は、代わりにCSSを使用できます。
-moz-transform-Origin: 25px 25px;
-ms-transform-Origin: 25px 25px;
-o-transform-Origin: 25px 25px;
-webkit-transform-Origin: 25px 25px;
transform-Origin: 25px 25px;
一部のブラウザ(Firefoxなど)は、相対値を正しく処理しません。
あなたが私のような人で、transform-Originでパンしてズームしたい場合は、もう少し必要になります。
// <g id="view"></g>
var view = document.getElementById("view");
var state = {
x: 0,
y: 0,
scale: 1
};
// Origin of transform, set to mouse position or pinch center
var oX = window.innerWidth/2;
var oY = window.innerHeight/2;
var changeScale = function (scale) {
// Limit the scale here if you want
// Zoom and pan transform-Origin equivalent
var scaleD = scale / state.scale;
var currentX = state.x;
var currentY = state.y;
// The magic
var x = scaleD * (currentX - oX) + oX;
var y = scaleD * (currentY - oY) + oY;
state.scale = scale;
state.x = x;
state.y = y;
var transform = "matrix("+scale+",0,0,"+scale+","+x+","+y+")";
//var transform = "translate("+x+","+y+") scale("+scale+")"; //same
view.setAttributeNS(null, "transform", transform);
};
ここでは動作しています: http://forresto.github.io/dataflow-prototyping/react/
matrix
変換を使用せずにスケーリングする場合:
transform="translate(cx, cy) scale(sx sy) translate(-cx, -cy)"
そして、これはCSSにあります:
transform: translate(cxpx, cypx) scale(sx, sy) translate(-cxpx, -cypx)
同様の問題がありました。しかし、私はDを使用して要素を配置し、CSSでtransformおよびtransitionを処理することを望んでいました。これは私の元のコードで、Chrome 65:
_//...
this.layerGroups.selectAll('.dot')
.data(data)
.enter()
.append('circle')
.attr('transform-Origin', (d,i)=> `${valueScale(d.value) * Math.sin( sliceSize * i)}
${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)}`)
//... etc (set the cx, cy and r below) ...
_
これにより、同じデータを使用してcx
、cy
、および_transform-Origin
_の値をjavascriptに設定できました。
ただし、これはFirefoxでは機能しませんでした!私がしなければならなかったのは、circle
タグでg
をラップし、同じものを使用してtranslate
でした上からの位置決め式。次に、circle
タグにg
を追加し、cx
およびcy
の値を_0
_に設定しました。そこから、transform: scale(2)
は期待どおりに中心から拡大縮小します。最終的なコードは次のようになりました。
_this.layerGroups.selectAll('.dot')
.data(data)
.enter()
.append('g')
.attrs({
class: d => `dot ${d.metric}`,
transform: (d,i) => `translate(${valueScale(d.value) * Math.sin( sliceSize * i)} ${valueScale(d.value) * Math.cos( sliceSize * i + Math.PI)})`
})
.append('circle')
.attrs({
r: this.opts.dotRadius,
cx: 0,
cy: 0,
})
_
この変更を行った後、transform: scale(2)
を追加するために、_.dot
_ではなくcircle
をターゲットとするようにCSSを変更しました。 _transform-Origin
_を使用する必要さえありませんでした。
注:
2番目の例では_d3-selection-multi
_を使用しています。これにより、属性ごとに_.attrs
_を繰り返す代わりに、オブジェクトを_.attr
_に渡すことができます。
文字列テンプレートリテラルを使用する場合、最初の例に示すように改行に注意してください。これにより、出力に改行が含まれ、コードが破損する場合があります。