class Manager { pendulums: Pendulum[] = [] timescale = 1; gravity = 9.81; playing = false; static Size = 20; constructor() { p.colorMode(p.HSB, 100); let count = 100; for (let i = 0; i < count; i++){ let rad = i / count / 1e3 + p.PI * 1.05; let hue = i / count * 100; let color = p.color(hue, 100, 100); this.pendulums.push( new Pendulum([1, 1, 1, 1, 1, 1, 1, 1], [50, 50, 50, 50, 50, 50, 50, 100 + i / count / 10000], color) ); } p.colorMode(p.RGB); } 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() { }, 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(), 1); this.pendulums.forEach(p => p.update(h)); } } draw(){ p.push() p.translate(p.width / 2, p.height / 2); this.pendulums.forEach(p => p.draw()); p.pop(); } }