simple-pendulum.js (3085B)
1 const App = { 2 data: function() { 3 return { 4 radius: 5, // The radius of the pendulum (m) 5 initialAngle: 5, // The initial angle of the pendulum (degrees) 6 gravity: 9.8, // The acceleration due to gravity (m/s/s) 7 time: 0, // The time (s) 8 active: false, // Whether the simulation is active 9 refreshRate: 0.01, // The simulation refresh rate (s) 10 intervalId: null, // The value returned by setInterval 11 infoVisible: false, 12 } 13 }, 14 computed: { 15 /** 16 * The period of the pendulum 17 */ 18 period: function() { 19 if (this.initialAngle === 0) return 0; 20 else return 2 * Math.PI * Math.sqrt(this.radius / this.gravity); 21 }, 22 23 /** 24 * The angle of the pendulum 25 */ 26 angle: function() { 27 if (this.initialAngle === 0) return 0; 28 else return this.initialAngle * Math.cos(this.time * 2 * Math.PI / this.period); 29 }, 30 31 /** 32 * The position of the pendulum mass 33 */ 34 position: function() { 35 return { 36 x: Math.sin(this.angle * 2 * Math.PI / 360) * this.radius, 37 y: -Math.cos(this.angle * 2 * Math.PI / 360) * this.radius, 38 }; 39 }, 40 41 /** 42 * The acceleration of the pendulum mass 43 */ 44 acceleration: function() { 45 return -Math.sin(this.angle * 2 * Math.PI / 360) * this.gravity; 46 }, 47 }, 48 methods: { 49 /** 50 * Handle a keyup event (implements keyboard shortcuts) 51 * @param {object} e - The event args 52 */ 53 keyup: function(e) { 54 if (e.key === "Escape") { 55 if (this.infoVisible) this.infoVisible = false; 56 else window.location.href = "../"; 57 } 58 }, 59 60 /** 61 * Toggle whether the simulation is active 62 */ 63 toggle: function() { 64 this.active = !this.active; 65 if (this.active) this.intervalID = setInterval(this.update, this.refreshRate * 1000); 66 else clearInterval(this.intervalID); 67 }, 68 69 /** 70 * Reset the simulation 71 */ 72 reset: function() { 73 this.time = 0; 74 }, 75 76 /** 77 * Update the simulation output 78 */ 79 update: function() { 80 this.time += this.refreshRate; 81 }, 82 }, 83 created: function() { 84 // Add keyup handler 85 window.addEventListener("keyup", this.keyup); 86 }, 87 destroyed: function() { 88 // Remove keyup handler 89 window.removeEventListener("keyup", this.keyup); 90 }, 91 } 92 93 94 95 // Create Vue app 96 function createApp() { 97 // Create app 98 Vue.createApp(App).mount("#app"); 99 100 // Unhide app divs 101 document.getElementById("input").hidden = false; 102 document.getElementById("output").hidden = false; 103 document.getElementById("data").hidden = false; 104 document.getElementById("info").hidden = false; 105 }