2016-08-30 25 views
5

Tôi đã lập trình một hàm xoay đối tượng xung quanh một đối tượng chính, như cách các hành tinh xoay quanh mặt trời.Tự động thêm các phần tử mới vào hàm

Tôi đang cố gắng tự động thêm các hành tinh mới trong hệ thống năng lượng mặt trời nhỏ của mình bằng cách nhấp một nút đơn giản. Chúng là tất cả các phần tử SVG. Tôi đang gặp khó khăn khi tìm hiểu cách tôi có thể tự động tạo ra các yếu tố mới xoay quanh mặt trời với hàm rotation(coorX, coorY, object) của tôi. Tất cả họ cần phải được đặt tên động và tự động định vị, điều này quá khó đối với tôi.

Mã của tôi cần phải trông như thế nào để tôi có thể đạt được điều này? Cảm ơn bạn trước vì bất kỳ trợ giúp/mẹo nào.

Dưới đây là mã của tôi:

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: Tôi cũng đang diễn ra chương trình mà mỗi hành tinh thêm sẽ được bố trí một chút xa hơn từ các điểm trung tâm (mặt trời) so với hành tinh thêm trước đó.

+1

Nội dung đầy đủ của câu hỏi của bạn phải được ** in ** câu hỏi của bạn, không chỉ liên kết. Liên kết thối, làm cho câu hỏi và câu trả lời của nó vô ích cho mọi người trong tương lai, và mọi người không nên phải ra khỏi trang web để giúp bạn.Đặt câu lệnh [mcve] ** vào **, lý tưởng là sử dụng Stack Snippets (nút thanh công cụ '<>') để làm cho nó chạy được. Hơn: [* Làm thế nào để tôi đặt một câu hỏi hay? *] (/ Help/how-to-ask) –

+1

Có vẻ như zessx đã tử tế, đủ để sửa nó cho bạn. –

Trả lời

5

Bạn đang đi đúng hướng với đối tượng ball (mặc dù tôi gọi nó là balls). Để tự động tạo ra một yếu tố circle bạn làm điều này:

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

Sau đó, bạn thiết lập các thuộc tính của nó (circle.setAttribute) và thêm nó vào các yếu tố id="Sun2".

Dưới đây là một chức năng makeBall nào đó trên cơ sở của một đối tượng đặc điểm kỹ thuật bạn vượt qua, trong đó có hai subobjects: element, trong đó xác định các phần tử, và animation trong đó xác định các hình ảnh động:

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

Sau đó, bạn sử dụng nó như thế này:

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

phần cuối cùng là để thay thế animate với một cái gì đó mà làm việc năng động với các thuộc tính bên trong ball:

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

Dưới đây là ví dụ xóa bluered khỏi đánh dấu và thêm chúng động khi chúng tôi bắt đầu. Tôi cũng đã gạt bỏ objectX và làm cho vòng quay luôn được liên quan đến black, và nối một số lĩnh vực để sử dụng khi thêm một quả bóng mới:

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>


Side lưu ý: Bạn có thể xem sử dụng requestAnimationFrame thay vì setInterval.

Lưu ý phụ 2: Theo như tôi có thể nói, cái bạn gọi là spin thực sự là khoảng cách từ trung tâm (ví dụ: bán kính của vòng tròn mà mỗi bóng sẽ mô tả xung quanh quả bóng đen).

+0

Xin chào, cảm ơn vì đã cố giúp đỡ. Nhưng tôi thấy đoạn mã không hoạt động như tôi muốn. Nó không thực sự thêm vào một hành tinh mới khi tôi nhấp vào nút, hoặc điều đó xảy ra bên ngoài kích thước màn hình. Ngoài ra, nó làm cho luân chuyển đi nhanh hơn rất nhiều trong khi tôi muốn nó ở lại giống nhau. Điều gì sẽ cần phải được thay đổi? – Zhyohzhy

+0

@ Zhyohzhy: Như tôi đã nói trong câu trả lời, tôi đã chỉ cho bạn cách tạo một phần tử động, nhưng để lại cho bạn để kết thúc nút để làm điều đó với các giá trị động. Chỉ cần trả lời một lần nhấp vào nút bằng cách gọi 'makeBall' với các giá trị mới. Tốc độ hoạt ảnh lại: Chỉ sử dụng cùng một cài đặt mà mã ban đầu của bạn đã thực hiện. –

+0

Bằng cách nào đó tôi không thể triển khai mã của bạn vào mã của tôi mà không có một số vấn đề. Tôi vẫn đang học các dây lập trình nói chung, bạn có phiền không nếu bạn cho thấy mã của bạn với tôi? – Zhyohzhy

Các vấn đề liên quan