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
115 lines • 3.6 kB
JavaScript
import Render2D from './Render2D';
export default class Animate2D extends Render2D {
constructor(opts) {
const { frameRenderCallback, autoPlay = true, frameRate = 60, title = 'Canvas', id = 'canvas_0', } = opts;
super({
...opts,
frameRate,
autoPlay,
title,
id
});
this.runState = 'play';
this.tick = 0;
this.defaultKeydownCallbackMap = {
// space bar pauses animation
'Space': {
callback: () => {
if (this.runState === 'play') {
// emit a pause event
const event = new CustomEvent('pause');
window.dispatchEvent(event);
}
else {
// emit a play event
const event = new CustomEvent('play');
window.dispatchEvent(event);
}
},
options: { preventDefault: true }
},
// return key steps animation forward
'Enter': {
callback: () => {
// emit a step event
const event = new CustomEvent('step');
window.dispatchEvent(event);
},
options: { preventDefault: true }
}
};
this.frameRenderCallback = frameRenderCallback;
this.frameRate = frameRate;
window.addEventListener('render', () => {
this.frameRenderCallback(this.tick, this);
});
window.addEventListener('stop', () => {
this.pause();
});
window.addEventListener('pause', () => {
this.pause();
});
window.addEventListener('play', () => {
this.play();
this.step();
});
window.addEventListener('step', () => {
if (this.runState === 'play') {
return;
}
this.step();
});
window.addEventListener('fps', (e) => {
const customEvent = e;
this.frameRate = customEvent.detail;
});
// create a keydown event handler
window.addEventListener('keydown', (e) => {
const mergedMaps = { ...this.defaultKeydownCallbackMap, ...opts.keydownCallbackMap };
const codeAction = mergedMaps === null || mergedMaps === void 0 ? void 0 : mergedMaps[e.code];
if (codeAction) {
const { callback, options } = codeAction;
callback(e);
if (options.preventDefault) {
e.preventDefault();
}
}
});
if (autoPlay) {
this.runState = 'play';
this.play();
}
else {
this.runState = 'pause';
this.pause();
}
this.step();
}
step() {
this.frameRenderCallback(this.tick, this);
this.tick++;
if (this.runState === 'play') {
setTimeout(() => requestAnimationFrame(() => this.step()), 1000 / this.frameRate);
}
}
play() {
this.runState = 'play';
this.step();
}
pause() {
this.runState = 'pause';
}
toggle() {
if (this.runState === 'play') {
this.pause();
}
else {
this.play();
}
}
stepForward() {
this.pause();
this.step();
}
}
//# sourceMappingURL=Animate2D.js.map