UNPKG

agentscape

Version:

Agentscape is a library for creating agent-based simulations. It provides a simple API for defining agents and their behavior, and for defining the environment in which the agents interact. Agentscape is designed to be flexible and extensible, allowing

150 lines (123 loc) 5.57 kB
// The control bar at the bottom of the canvas pane. // it contains the play/pause button, the step button, and the speed control import Log from '../../Log' enum PlayPauseState { Play = 'Play', Pause = 'Pause' } class AnimationToolbar extends HTMLElement { private playPauseBtnRef: HTMLButtonElement private stepBtnRef: HTMLButtonElement private fpsSetterRef: HTMLInputElement private fpsDisplayRef: HTMLInputElement private playPauseState: PlayPauseState public connectedCallback() { const style = ` .row { border-top: 1px solid black; display: flex; justify-content: flex-start; align-items: center; } button { width: 50px; height: 25px; margin: 3px; } label { margin-left: 5px; margin-right: 3px; } #fpsDisplay { width: 35px; } ` const template = document.createElement('template') template.innerHTML = ` <style>${style}</style> <div class="row"> <button title="Space" id="play-pause"></button> <button title="Enter" id="step">Step</button> <label for="fpsSetter">Framerate</label> <input type="range" min="1" max="60" id="fpsSetter"> <input type="number" id="fpsDisplay" disabled> <label for="toggleInspectorPane">Inspector</label> <input type="checkbox" id="toggleInspectorPane"> <label for="setLogLevel">Log Level</label> <select id="setLogLevel"> <option value=-1>Off</option> <option value=0>Debug</option> <option value=1>Info</option> <option value=2>Warn</option> <option value=3>Error</option> </select> <div> ` const shadowRoot = this.attachShadow({mode: 'open'}) shadowRoot.appendChild(template.content.cloneNode(true)) this.fpsDisplayRef = shadowRoot.getElementById('fpsDisplay') as HTMLInputElement this.fpsSetterRef = shadowRoot.getElementById('fpsSetter') as HTMLInputElement this.playPauseBtnRef = shadowRoot.getElementById('play-pause') as HTMLButtonElement this.stepBtnRef = shadowRoot.getElementById('step') as HTMLButtonElement // the inspector pane toggle emits a custom event to toggle the inspector pane // the event detail is wherever the checkbox is checked or not const toggleInspectorPane = shadowRoot.getElementById('toggleInspectorPane') as HTMLInputElement toggleInspectorPane.addEventListener('change', (e) => { window.dispatchEvent(new CustomEvent('toggleInspectorPane', {detail: (e.target as HTMLInputElement).checked})) }) const toggleLogs = shadowRoot.getElementById('setLogLevel') as HTMLSelectElement toggleLogs.addEventListener('change', (e) => { Log.setLevel(parseInt((e.target as HTMLInputElement).value)) }) this.playPauseBtnRef.addEventListener('click', this.handlePlayPauseClick.bind(this)) this.stepBtnRef.addEventListener('click', this.handleStepClick.bind(this)) // set playPauseState to Play if autoPlay is true if (this.getAttribute('autoPlay') === 'true') { this.playPauseState = PlayPauseState.Play this.playPauseBtnRef.innerHTML = PlayPauseState.Pause } else { this.playPauseState = PlayPauseState.Pause this.playPauseBtnRef.innerHTML = PlayPauseState.Play } // init the frame rate setter const fps = this.getAttribute('fps') || '60' this.fpsDisplayRef.value = fps this.fpsSetterRef.value = fps this.fpsSetterRef.addEventListener('change', this.handleFpsChange.bind(this)) // keep the play/pause button in sync with the simulation state window.addEventListener('play', () => { this.playPauseState = PlayPauseState.Play this.playPauseBtnRef.innerText = PlayPauseState.Pause }) window.addEventListener('pause', () => { this.playPauseState = PlayPauseState.Pause this.playPauseBtnRef.innerText = PlayPauseState.Play }) } private handlePlayPauseClick() { if (this.playPauseState === PlayPauseState.Play) { // if the simulation is playing, pause it this.playPauseBtnRef.innerText = PlayPauseState.Play this.playPauseState = PlayPauseState.Pause // emit a custom 'play' event window.dispatchEvent(new CustomEvent('pause')) } else { // if the simulation is paused, play it this.playPauseBtnRef.innerText = PlayPauseState.Pause this.playPauseState = PlayPauseState.Play // emit a custom 'pause' event window.dispatchEvent(new CustomEvent('play')) } } private handleStepClick() { // emit a custom 'step' event if the simulation is paused window.dispatchEvent(new CustomEvent('step')) } private handleFpsChange() { // emit a custom 'fps' event this.fpsDisplayRef.value = this.fpsSetterRef.value window.dispatchEvent(new CustomEvent('fps', {detail: this.fpsSetterRef.value})) } } customElements.define('animation-toolbar', AnimationToolbar) export default AnimationToolbar