2016-09-30 3 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>

당신은 하나가 <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>

그런 다음 나는 회전이 그 변환을 적용하면됩니다. 내가 원하는 경우

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

그럼, 나는 그룹의 변환을 업데이트함으로써 RECT이 더욱 오른쪽으로 이동 할 수 있습니다.

<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>이 ("좌표 공간"그것의 자신의 작은 세계에 공식 용어입니다 :)과에서 무슨 일이 일어나고 있는지의 행복하게 인식하지 못하는 것입니다 그것의 부모 요소.

위에서 배운 것을 사용하면 애니메이션의 종류를 쉽게 만들 수 있습니다. 다음 애니메이션은 세 단계로 구성됩니다. 먼저 직사각형을 오른쪽으로 이동시킨 다음 회전시키고 다시 오른쪽으로 계속 진행합니다. 가운데에있는 회전은 다시 오른쪽으로 이동하는 세 번째 단계에는 영향을 미치지 않습니다.위의 예에서

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>

, 나는 "외부"상위 그룹에 밖을 변환 분리,하지만 우리는 정말 할 필요가 없습니다. 변환 작업을 단일 변환으로 중첩 할 수 있습니다.

그래서 우리는 위의 제 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