2016-09-30 22 views
0

プレーンなjavascriptを使用してsvg要素をその変換で操作するベストプラクティスを理解してください。回転後のSVG要素の移動

私は座標系ノードを受け継がと連鎖している理解などなど

私は何を達成しようとしていることは、回転後の要素の元の翻訳を継続することです。回転が適用された後、軸に沿ってではありません。

最初のtranslate-transformをクローンコピーして変換リストの最後に追加する必要がありますか?

誰かが雄弁な方法で光を放つことができれば、多くのおかげです。

答えて

1

最善の方法は、行列変換を作成し、次にさまざまな変換を要求し、consolidate()メソッドを使用することです。以下は、これを実現する方法は、変換を入れ子にすることである例

<!DOCTYPE HTML> 
 
<html> 
 
<head> 
 
    <title>Transform Request</title> 
 
</head> 
 

 
<body onload=showSVGSource()> 
 
<b><center>Transform Request Object + consolidate</b> 
 
<div id=svgDiv style=background:lime;width:400px;height:400px; > 
 
<svg id=mySVG width=400 height=400 > 
 
<circle id=myCircle cx=0 cy=0 r=150 fill=yellow transform="translate(200,200)" /> 
 
</svg> 
 
</div> 
 
<br> 
 
<button onClick=translateCircle()>translate</button> 
 
<button onClick=scaleCircle()>scale</button> 
 
<br> 
 
<textarea id=svgSourceValue style=width:500px;height:100px;></textarea> 
 
<center> 
 
<script> 
 
function translateCircle() 
 
{ 
 
    var objTransformRequestObj = mySVG.createSVGTransform() 
 
    //---attach new transform to element, init its transform list--- 
 
    var myTransListAnim=myCircle.transform 
 
    var objTransList=myTransListAnim.baseVal 
 

 
    objTransformRequestObj.setTranslate(40,0) 
 
    objTransList.appendItem(objTransformRequestObj) 
 
    objTransList.consolidate() 
 
    showSVGSource() 
 

 
} 
 
function scaleCircle() 
 
{ 
 
    var objTransformRequestObj = mySVG.createSVGTransform() 
 
    //---attach new transform to element, init its transform list--- 
 
    var myTransListAnim=myCircle.transform 
 
    var objTransList=myTransListAnim.baseVal 
 

 
    objTransformRequestObj.setScale(.5,.3) 
 
    objTransList.appendItem(objTransformRequestObj) 
 
    objTransList.consolidate() 
 
    showSVGSource() 
 
} 
 
function showSVGSource() 
 
{ 
 
    svgSourceValue.value=svgDiv.innerHTML 
 
} 
 
</script> 
 
</body> 
 

 
</html>

3

です。たとえば、次のサンプルSVGを見てください。

<svg width="600" height="200"> 
 
    <g> 
 
    <rect x="0" y="50" width="100" height="100" fill="blue"/> 
 
    </g> 
 
</svg>

あなたは1つが<rect><g>と別のものに変換を適用することができます。彼らは独立していますが、総合的な効果のために結合します。

たとえば、すべてを正しく移動したい場合は、グループに変換トランスフォームを適用できます。

<svg width="600" height="200"> 
 
    <g transform="translate(200,0)"> 
 
    <rect x="0" y="50" width="100" height="100" fill="blue"/> 
 
    </g> 
 
</svg>

Iが所定の位置に四角形を回転させたい場合はその後、私は回転がその変換を適用することにより、これを行うことができます。

<svg width="600" height="200"> 
 
    <g transform="translate(200,0)"> 
 
    <rect x="0" y="50" width="100" height="100" fill="blue" 
 
      transform="rotate(45,50,100)"/> 
 
    </g> 
 
</svg>

私が欲しい場合はその後、私は、グループの変換更新することで、さらに右の矩形を移動することができます。

<svg width="600" height="200"> 
 
    <g transform="translate(400,0)"> 
 
    <rect x="0" y="50" width="100" height="100" fill="blue" 
 
      transform="rotate(45,50,100)"/> 
 
    </g> 
 
</svg>

これについて考えるための方法は、(「座標空間」<rect>は、それ自身の小さな世界であるということである公式の用語である:)とで何が起こっているかの穏やか気づきませんその親要素。

私たちが上で学んだことを使用すれば、後に続くアニメーションの種類を簡単に作成できます。次のアニメーションは3つのフェーズで構成されています。最初に矩形を右に移動し、次にそれを回転させ、次に右に移動します。真ん中の回転は3番目のフェーズには影響しません。そこで再び右に移動します。上記の例で

var outer = document.getElementById("outer"); 
 
var inner = document.getElementById("inner"); 
 

 
var tx = 0;  // the animated X position 
 
var angle = 0; // the animated angle 
 

 
/* 
 
* The first phase of the animation. 
 
* Function to step to the right until we hit tx=200. 
 
*/ 
 
var stepRightTo200 = function() { 
 
    setTimeout(function() { 
 
    tx += 4; 
 
    outer.setAttribute('transform', 'translate('+tx+',0)'); 
 
    if (tx < 200) // schedule another step in this phase 
 
     stepRightTo200(); 
 
    else   // start next phase of animation 
 
     rotateTo45(); 
 
    }, 32); 
 
}; 
 

 
/* 
 
* The second phase of the animation. 
 
* Step the angle around until we hit 45 degrees. 
 
*/ 
 
var rotateTo45 = function() { 
 
    setTimeout(function() { 
 
    angle += 1; 
 
    inner.setAttribute('transform', 'rotate('+angle+',50,100)'); 
 
    if (angle < 45) 
 
     rotateTo45() 
 
    else 
 
     stepRightTo400(); // start third phase of animation 
 
    }, 32); 
 
}; 
 

 
/* 
 
* The third phase of the animation. 
 
* Step to the right until we hit tx=400. 
 
*/ 
 
var stepRightTo400 = function() { 
 
    setTimeout(function() { 
 
    tx += 4; 
 
    outer.setAttribute('transform', 'translate('+tx+',0)'); 
 
    if (tx < 400) 
 
     stepRightTo400(); 
 
    }, 32); 
 
}; 
 

 
// Kick off first phase of animation 
 
stepRightTo200();
<svg width="600" height="200"> 
 
    <g id="outer"> 
 
    <rect id="inner" x="0" y="50" width="100" height="100" fill="blue"/> 
 
    </g> 
 
</svg>

、私は「外側」親グループに出る変換を分離しているが、私たちは本当にそれを行う必要はありません。変換操作を1つの変換にネストできます。

だから我々は、上記に三SVGの例を簡略化することができます:変換「外側」は変換リストの最初のものとなる

<svg width="600" height="200"> 
 
    <rect x="0" y="50" width="100" height="100" fill="blue" 
 
     transform="translate(400,0) rotate(45,50,100)"/> 
 
</svg>

。これは、マルチパートトランスフォームを作成する必要がある場合に、マルチパートトランスフォームをコンセプトにするための良い方法です。まずネストされたグループ構造を作成(または想像)し、変換を「外側」(左)から「内側」(右)に適用します。

最後に、このネストされていないフォームを使用してアニメーションスクリプトを書き直すことができます。

var inner = document.getElementById("inner"); 
 

 
var tx = 0;  // the animated X position 
 
var angle = 0; // the animated angle 
 

 
/* 
 
* The first phase of the animation. 
 
* Function to step to the right until we hit tx=200. 
 
*/ 
 
var stepRightTo200 = function() { 
 
    setTimeout(function() { 
 
    tx += 4; 
 
    inner.setAttribute('transform', 
 
         'translate('+tx+',0) rotate('+angle+',50,100)'); 
 
    if (tx < 200) // schedule another step in this phase 
 
     stepRightTo200(); 
 
    else   // start next phase of animation 
 
     rotateTo45(); 
 
    }, 32); 
 
}; 
 

 
/* 
 
* The second phase of the animation. 
 
* Step the angle around until we hit 45 degrees. 
 
*/ 
 
var rotateTo45 = function() { 
 
    setTimeout(function() { 
 
    angle += 1; 
 
    inner.setAttribute('transform', 
 
         'translate('+tx+',0) rotate('+angle+',50,100)'); 
 
    if (angle < 45) 
 
     rotateTo45() 
 
    else 
 
     stepRightTo400(); // start third phase of animation 
 
    }, 32); 
 
}; 
 

 
/* 
 
* The third phase of the animation. 
 
* Step to the right until we hit tx=400. 
 
*/ 
 
var stepRightTo400 = function() { 
 
    setTimeout(function() { 
 
    tx += 4; 
 
    inner.setAttribute('transform', 
 
         'translate('+tx+',0) rotate('+angle+',50,100)'); 
 
    if (tx < 400) 
 
     stepRightTo400(); 
 
    }, 32); 
 
}; 
 

 
// Kick off first phase of animation 
 
stepRightTo200();
<svg width="600" height="200"> 
 
    <rect id="inner" x="0" y="50" width="100" height="100" fill="blue"/> 
 
</svg>

これはあなたが仕事を変える方法を理解するのに役立ちます願っています。

+0

非常に有益です。本当に助けてくれてありがとう。 – daniel

関連する問題