class Manager { pendula: Pendulum[] = [] timescale = 1; gravity = 9.81; playing = false; static Size = 200; init(){ // @ts-ignore const {createApp} = Vue; createApp({ data() { return { gravity: manager.gravity, timescale: manager.timescale, playingBtn: "play" }; }, watch: { gravity(newGravity: number) { manager.gravity = newGravity; }, timescale(newScale: number){ manager.timescale = newScale; } }, methods: { togglePlay(){ manager.playing = !manager.playing; this.playingBtn = manager.playing ? "pause" : "play"; } }, name: "Simulation" }).mount("#simulation"); createApp({ data(){ return { segmentCount: 1, maxSegmentCount: 30, masses: [], lengths: [], startAngle: 90, color: "#ffffff", rainbow: false, multiple: false, pendulumCount: 10, changeProperty: "angle", changeAmount: 0.05, changeIndex: 0 } }, methods: { add() { if (this.multiple){ } else { let color = p.color(this.color) let M = this.masses.slice(0, this.segmentCount); let L = this.lengths.slice(0, this.segmentCount); let newPendulum = new Pendulum(M, L, color, this.startAngle); manager.pendula.push(newPendulum); } p.colorMode(p.HSB, 100); p.colorMode(p.RGB); }, deleteAll(){ if (confirm("Delete all pendulums?")){ manager.pendula.splice(0); } }, resetMasses(){ for (let i = 0; i < this.maxSegmentCount; i++) this.masses[i] = 1; }, resetLengths() { for (let i = 0; i < this.maxSegmentCount; i++) this.lengths[i] = 1; }, normalize(){ let L: [number] = this.lengths; let sum = L.slice(0, this.segmentCount).reduce((p, n) => p + n); let maxLength = Manager.Size / 2; let factor = maxLength / sum; for (let i = 0; i < this.segmentCount; i++) this.lengths[i] *= factor; } }, mounted() { this.resetMasses(); this.resetLengths(); }, name: "Preparation" }).mount("#preparation"); } update(){ if (this.playing) { const h = this.timescale / Math.max(p.frameRate(), 30); this.pendula.forEach(p => p.update(h)); } } draw(){ p.push() p.translate(p.width / 2, p.height / 2); this.pendula.forEach(p => p.draw()); p.pop(); } }