2016-08-30 3 views
5

행성이 태양 주위를 어떻게 회전하는지 등 주 객체를 중심으로 객체를 회전시키는 함수를 프로그래밍했습니다.함수에 새 요소를 동적으로 추가합니다.

버튼을 한 번 클릭하여 작은 태양계에 새로운 행성을 동적으로 추가하려고합니다. 그것들은 모두 SVG 요소입니다. 내 rotation(coorX, coorY, object) 함수로 태양 주위를 회전하는 새로운 요소를 동적으로 생성 할 수있는 방법을 찾는 데 어려움을 겪고 있습니다. 그들은 모두 동적으로 이름이 붙여지고 동적으로 배치되어야합니다. 이것은 나에게 너무 어렵습니다.

이 작업을 수행하기 위해 내 코드가 어떻게 표시되어야합니까? 도움말/팁에 대해 미리 감사드립니다.

var objectX = "black"; 
 
function addObject(){ 
 
    objectX = "blue"; 
 
} 
 

 
function rotation(coorX, coorY, object) { 
 
\t object.side += (1.0/object.speed); 
 
\t var ang = object.side * 2.0 * Math.PI/180.0; 
 
\t var r = object.spin; 
 
    
 
\t return { 
 
\t \t x: Math.cos(ang) * r - Math.sin(ang) * r + coorX, 
 
\t \t y: Math.sin(ang) * r + Math.cos(ang) * r + coorY 
 
\t }; 
 
    } 
 
    
 
    function rotationball (circle) { 
 
\t var x, y, x_black, y_black, e, newpos; 
 
\t e = document.getElementById (circle); 
 
\t x_black = parseFloat (document.getElementById (objectX).getAttribute ("cx")); 
 
\t y_black = parseFloat (document.getElementById (objectX).getAttribute ("cy")); 
 
\t newpos = rotation(x_black, y_black, ball[circle]); 
 
    
 
\t e.setAttribute ("cx", newpos.x); 
 
\t e.setAttribute ("cy", newpos.y); 
 
\t } 
 
    
 
    var ball = { 
 
    blue: \t {speed: 1.2, \t spin: 100, \t side: 0.0} , 
 
    red: \t {speed: 1.2, \t spin: 200, \t side: 0.0} 
 
\t }; 
 
    
 
    function animate() { 
 
    \t rotationball("blue"); 
 
    \t rotationball("red"); 
 
\t }  
 

 
var animateInterval = setInterval(animate, 1000/60);
.st0{fill:black;} 
 
.st1{fill:blue;} 
 
.st2{fill:red;}
<div class="spinning"> <svg xmlns="http://www.w3.org/2000/svg" id="solly" viewBox="0 0 1000 600"><g id="Sun2"> 
 
\t \t <circle id="black" class="st0" cx="500" cy="300.8" r="10"/> 
 
\t \t <circle id="blue" class="st1" cx="375.4" cy="289.7" r="10"/> \t 
 
    <circle id="red" class="st2" cx="375.4" cy="289.7" r="10"/> \t 
 
    
 
</div> 
 
<button type="button" onclick="addObject()"> 
 
button 
 
</button>
PS :

여기 내 코드의 나는 또한 추가 된 각 행성은 이전에 추가 행성보다 중앙 지점 (태양)에서 조금 더 멀리 위치 할 것이라는 점을 프로그램 할 거라고.

+1

귀하의 질문에 대한 전체 내용은 귀하의 질문에 ** 연결되어있을뿐만 아니라 **되어야합니다. 링크 썩어, 미래의 사람들에게 질문과 그 대답을 쓸모없는 만들고, 사람들이 당신을 돕기 위해 오프 사이트로 이동해서는 안됩니다.질문에 [mcve] **를 넣으십시오. Stack Snippets ('<>'도구 모음 단추)를 사용하여 실행 가능하게 만드는 것이 이상적입니다. 기타 : [* 좋은 질문을하는 방법 *] (/ help/how-to-ask) –

+1

zessx가 친절하게 고칠 수있는 것처럼 보입니다. –

답변

5

ball 개체로 궤도에 있습니다 (단, balls이라고 부릅니다). 동적으로 circle 요소를 생성하려면 다음을 수행

var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 

이 그럼 당신은 그 속성 (circle.setAttribute)을 설정하고 id="Sun2" 요소에 추가합니다. 여기

당신이하는 통과 사양 개체를 기준으로 두 개의 하위 객체를 가지고 수행하는 makeBall 함수의 : 요소를 정의 element을, 그리고 애니메이션 정의 animation : 그럼 당신은 사용

function makeBall(spec) { 
    // Create the element 
    var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 
    // Set its various attributes 
    ["id", "cx", "cy", "r", "class"].forEach(function(attrName) { 
    circle.setAttribute(attrName, spec.element[attrName]); 
    }); 
    // Add it to the sun 
    document.getElementById("Sun2").appendChild(circle); 
    // Remember its animation settings in `ball` 
    ball[spec.element.id] = spec.animation; 
} 

을 이 같은이 : 마지막 부분은 ball 내부의 속성을 동적으로 작동 뭔가 애니메이션을 대체 할

makeBall({ 
    element: {id: "blue", class: "st1", cx: "375.4", cy: "289.7", r: "10"}, 
    animation: {speed: 1.2, spin: 100, side: 0.0} 
}); 

입니다

:

function animate() { 
    Object.keys(ball).forEach(function(id) { 
    rotationball(id); 
    }); 
} 

다음은 마크 업에서 bluered을 제거하고 우리가 시작할 때 동적으로 추가하는 예입니다. 또한 objectX 제거하고 회전이 항상 black을 기준으로 할 수 있도록, 새로운 볼을 추가 할 때 사용하는 일부 필드를 엮은 왔 :

var ball = {}; 
 

 
makeBall({ 
 
    element: {id: "blue", class: "st1", r: "10"}, 
 
    animation: {speed: 1.2, spin: 20, side: 0.0} 
 
}); 
 
makeBall({ 
 
    element: {id: "red", class: "st2", r: "10"}, 
 
    animation: {speed: 1.2, spin: 40, side: 120.0} 
 
}); 
 
makeBall({ 
 
    element: {id: "yellow", class: "st3", r: "10"}, 
 
    animation: {speed: 1.2, spin: 60, side: 240.0} 
 
}); 
 

 
function makeBall(spec) { 
 
    // Create the element 
 
    var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 
 
    // Set its various attributes 
 
    ["id", "cx", "cy", "r", "class"].forEach(function(attrName) { 
 
    if (spec.element[attrName]) { 
 
     circle.setAttribute(attrName, spec.element[attrName]); 
 
    } 
 
    }); 
 
    // Add it to the sun 
 
    document.getElementById("Sun2").appendChild(circle); 
 
    // Remember its animation settings in `ball` 
 
    ball[spec.element.id] = spec.animation; 
 
} 
 

 
function addObject() { 
 
    // Create a spec to use with makeBall from the fields 
 
    var spec = { 
 
    element: { 
 
     id: document.getElementById("new-id").value, 
 
     class: document.getElementById("new-class").value, 
 
     r: parseFloat(document.getElementById("new-r").value) 
 
    }, 
 
    animation: { 
 
     speed: parseFloat(document.getElementById("new-speed").value), 
 
     spin: parseFloat(document.getElementById("new-spin").value), 
 
     side: parseFloat(document.getElementById("new-side").value) 
 
    } 
 
    }; 
 
    // Some minimal validation 
 
    if (!spec.element.id || !spec.element.r || !spec.animation.speed || !spec.animation.spin || isNaN(spec.animation.side)) { 
 
    alert("Need all values to add a ball"); 
 
    } else if (ball[spec.element.id]) { 
 
    alert("There is already a ball '" + spec.element.id + "'"); 
 
    } else { 
 
    // Do it! 
 
    makeBall(spec); 
 
    } 
 
} 
 

 
function rotation(coorX, coorY, object) { 
 
    object.side += (1.0/object.speed); 
 
    var ang = object.side * 2.0 * Math.PI/180.0; 
 
    var r = object.spin; 
 

 
    return { 
 
    x: Math.cos(ang) * r - Math.sin(ang) * r + coorX, 
 
    y: Math.sin(ang) * r + Math.cos(ang) * r + coorY 
 
    }; 
 
} 
 

 
function rotationball(circle) { 
 
    var x, y, x_black, y_black, e, newpos, black; 
 

 
    // We always rotate around black 
 
    black = document.getElementById("black"); 
 
    
 
    // Get this circle and update its position 
 
    e = document.getElementById(circle); 
 
    x_black = parseFloat(black.getAttribute("cx")); 
 
    y_black = parseFloat(black.getAttribute("cy")); 
 
    newpos = rotation(x_black, y_black, ball[circle]); 
 

 
    e.setAttribute("cx", newpos.x); 
 
    e.setAttribute("cy", newpos.y); 
 
} 
 

 
function animate() { 
 
    Object.keys(ball).forEach(function(id) { 
 
    rotationball(id); 
 
    }); 
 
} 
 

 
var animateInterval = setInterval(animate, 1000/60);
.st0 { 
 
    fill: black; 
 
} 
 
.st1 { 
 
    fill: blue; 
 
} 
 
.st2 { 
 
    fill: red; 
 
} 
 
.st3 { 
 
    fill: yellow; 
 
} 
 
.st4 { 
 
    fill: orange; 
 
}
<div>Add ball: 
 
    <label> 
 
    ID: <input type="text" id="new-id" value="newball"> 
 
    </label> 
 
    <label> 
 
    R: <input type="text" id="new-r" value="10"> 
 
    </label> 
 
    <label> 
 
    Speed: <input type="text" id="new-speed" value="1.2"> 
 
    </label> 
 
    <label> 
 
    Spin: <input type="text" id="new-spin" value="80"> 
 
    </label> 
 
    <label> 
 
    Side: <input type="text" id="new-side" value="0.0"> 
 
    </label> 
 
    <label> 
 
    Class: <input type="text" id="new-class" value="st4"> 
 
    </label> 
 
    <button type="button" onclick="addObject()"> 
 
    Make Ball 
 
    </button> 
 
</div> 
 

 
<div class="spinning"> 
 
    <svg xmlns="http://www.w3.org/2000/svg" id="solly" viewBox="0 0 1000 600"> 
 
    <g id="Sun2"> 
 
     <circle id="black" class="st0" cx="500" cy="300.8" r="10" /> 
 
    </g> 
 
    </svg> 
 
</div>


사이드 참고 : setInterval 대신 requestAnimationFrame을 사용하는 것이 좋습니다.

사이드 노트 2 : 내가 알 수있는 한, 실제로는 spin은 센터로부터의 거리입니다 (예 : 각 공이 검은 공 둘레에서 설명 할 원의 반경).

+0

안녕하세요. 도와 주셔서 감사합니다. 그러나 나는 내가 원했던 것처럼 스 니펫이 작동하지 않는 것을 본다. 버튼을 클릭 할 때 실제로 새로운 행성을 추가하지 않습니다. 그렇지 않으면 화면 크기 밖에서 발생합니다. 또한, 회전을 훨씬 빠르게하는 반면, 회전을 유지하려고합니다. 무엇이 변경되어야합니까? – Zhyohzhy

+0

@ Zhyohzhy : 대답에서 말했듯이 요소를 동적으로 만드는 방법을 보여 주었지만 동적 값을 사용하여 요소를 만들기 위해 버튼을 연결해야했습니다. 'makeBall'를 새로운 값으로 호출하여 버튼 클릭에 응답하십시오. 애니메이션 속도 향상 : 원본 코드와 동일한 설정을 사용하고 있습니다. –

+0

어쨌든 나는 어떤 문제없이 내 코드를 구현할 수 없다. 나는 여전히 프로그래밍의 밧줄을 배우고 있는데, 내 코드를 보여 주면 되겠습니까? – Zhyohzhy

관련 문제