import { Display } from './display.js'; import { Overlay } from './overlay.js'; import { Pointer } from './pointer.js'; import { Objects } from './objects.js'; import { Toolbar } from './toolbar.js'; import { PlayPause } from './tools/play-pause.js'; import { SCALE_MAX, SCALE_MIN} from './config.js'; export class Sim { info = {}; time = undefined; nextZoom = undefined; playing = true; display = undefined; overlay = undefined; pointer = undefined; objects = undefined; init(divId) { this.divId = divId; const div = document.getElementById(this.divId); this.div = div; this.display = new Display(this); this.overlay = new Overlay(this); this.pointer = new Pointer(this); this.objects = new Objects(this); this.toolbar = new Toolbar(this); // Set up toolbar this.toolbar.addTool(new PlayPause(this.toolbar)); // Initiate main loop this.time = document.timeline.currentTime; requestAnimationFrame(t => this.loop(t)); } scheduleZoom({x, y}, factor) { this.nextZoom = {x, y, factor}; } zoom({x, y, factor}) { // x, y are the mouse coordinates, which should be the center of the new view frame // the new view origin should be x, y minus half the new view width and height // compute new scale this.display.scale = this.display.scale * factor; if (this.display.scale > SCALE_MAX) this.display.scale = SCALE_MAX; if (this.display.scale < SCALE_MIN) this.display.scale = SCALE_MIN; // compute coordinates of new view frame this.display.viewOrigin.x = x - this.display.width / 2; this.display.viewOrigin.y = y - this.display.height / 2; } // Transform display coordinates to simulator coordinates using scale and viewOrigin screenToSim(x, y) { return this.display.screenToSim(x, y); } play() { this.playing = true; } pause() { this.playing = false; } // Main loop loop(currentTime) { const elapsedTime = currentTime - this.time; this.time = currentTime; if (this.nextZoom) { this.zoom(this.nextZoom); this.nextZoom = undefined; } this.info['scale'] = this.display.scale; this.objects.computeFrame(elapsedTime); this.display.fillCanvas(); this.display.drawObjects(); this.overlay.updateDraggable(); this.overlay.renderInfo(); requestAnimationFrame(t => this.loop(t)); } }