spring-mass-system.js (3166B)
1 const App = { 2 data: function() { 3 return { 4 mass: 5, // The mass of the object (Kg) 5 initialPosition: 5, // The object's initial position (m) 6 stiffness: 5, // The spring stiffness (N/m) 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 object 17 */ 18 period: function() { 19 if (this.initialPosition === 0) return 0; 20 else return 2 * Math.PI * Math.sqrt(this.mass / this.stiffness); 21 }, 22 23 /** 24 * The position of the object 25 */ 26 position: function() { 27 if (this.initialPosition === 0) return 0; 28 else return this.initialPosition * Math.cos(this.time * 2 * Math.PI / this.period); 29 }, 30 31 /** 32 * The velocity of the object 33 */ 34 velocity: function() { 35 if (this.initialPosition === 0) return 0; 36 else return -1 * this.initialPosition * Math.sin(this.time * 2 * Math.PI / this.period) * 2 * Math.PI / this.period; 37 }, 38 39 /** 40 * The spring force 41 */ 42 force: function() { 43 return -1 * this.stiffness * this.position; 44 }, 45 46 /** 47 * The acceleration of the object 48 */ 49 acceleration: function() { 50 return this.force / this.mass; 51 }, 52 }, 53 methods: { 54 /** 55 * Handle a keyup event (implements keyboard shortcuts) 56 * @param {object} e - The event args 57 */ 58 keyup: function(e) { 59 if (e.key === "Escape") { 60 if (this.infoVisible) this.infoVisible = false; 61 else window.location.href = "../"; 62 } 63 }, 64 65 /** 66 * Toggle whether the simulation is active 67 */ 68 toggle: function() { 69 this.active = !this.active; 70 if (this.active) this.intervalID = setInterval(this.update, this.refreshRate * 1000); 71 else clearInterval(this.intervalID); 72 }, 73 74 /** 75 * Reset the simulation 76 */ 77 reset: function() { 78 this.time = 0; 79 }, 80 81 /** 82 * Update the simulation output 83 */ 84 update: function() { 85 this.time += this.refreshRate; 86 }, 87 }, 88 created: function() { 89 // Add keyup handler 90 window.addEventListener("keyup", this.keyup); 91 }, 92 destroyed: function() { 93 // Remove keyup handler 94 window.removeEventListener("keyup", this.keyup); 95 }, 96 } 97 98 99 100 // Create Vue app 101 function createApp() { 102 // Create app 103 Vue.createApp(App).mount("#app"); 104 105 // Unhide app divs 106 document.getElementById("input").hidden = false; 107 document.getElementById("output").hidden = false; 108 document.getElementById("data").hidden = false; 109 document.getElementById("info").hidden = false; 110 }