play/pause button
This commit is contained in:
parent
d96aefd3f2
commit
6fd3bcae15
@ -12,3 +12,5 @@ export const MOTION_TIME_SCALE = 0.001;
|
||||
export const OFFSCREEN_OBJECT_LINE_SCALE = 5;
|
||||
export const OFFSCREEN_OBJECT_LINE_WIDTH = 1.5;
|
||||
export const OFFSCREEN_OBJECT_ARROWHEAD_LENGTH = 15;
|
||||
export const ZOOM_IN_FACTOR = 2;
|
||||
export const ZOOM_OUT_FACTOR = 0.5;
|
||||
|
||||
@ -15,7 +15,7 @@ body {
|
||||
}
|
||||
|
||||
div[id=simulator] {
|
||||
position: absolute;
|
||||
position: float;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
|
||||
14
pointer.js
14
pointer.js
@ -1,4 +1,8 @@
|
||||
import { POINTER_HISTORY_SIZE } from './config.js';
|
||||
import {
|
||||
POINTER_HISTORY_SIZE,
|
||||
ZOOM_IN_FACTOR,
|
||||
ZOOM_OUT_FACTOR,
|
||||
} from './config.js';
|
||||
|
||||
export class Pointer {
|
||||
sim = undefined;
|
||||
@ -11,30 +15,36 @@ export class Pointer {
|
||||
// Monitor mouse movements
|
||||
const el = window;
|
||||
el.addEventListener('mousemove', e => {
|
||||
// e.preventDefault();
|
||||
this.handlePointerMove(this.sim.screenToSim(e.clientX, e.clientY));
|
||||
});
|
||||
|
||||
// Monitor touch events
|
||||
el.addEventListener('touchmove', e => {
|
||||
// e.preventDefault();
|
||||
const {pageX, pageY} = e.touches[0];
|
||||
this.handlePointerMove(this.sim.screenToSim(pageX, pageY));
|
||||
});
|
||||
|
||||
el.addEventListener('pointerdown', e => {
|
||||
// e.preventDefault();
|
||||
this.handlePointerDown(this.sim.screenToSim(e.clientX, e.clientY));
|
||||
});
|
||||
|
||||
el.addEventListener('pointerup', e => {
|
||||
// e.preventDefault();
|
||||
this.handlePointerUp(this.sim.screenToSim(e.clientX, e.clientY));
|
||||
});
|
||||
|
||||
el.addEventListener('click', e => {
|
||||
// e.preventDefault();
|
||||
});
|
||||
|
||||
// Monitor wheel events
|
||||
el.addEventListener('wheel', e => {
|
||||
// e.preventDefault();
|
||||
// Wheel scroll down => positive deltaY => ZOOM IN
|
||||
const factor = e.deltaY > 0 ? 2 : 0.5;
|
||||
const factor = e.deltaY > 0 ? ZOOM_IN_FACTOR : ZOOM_OUT_FACTOR;
|
||||
this.sim.scheduleZoom(this.sim.screenToSim(e.clientX, e.clientY), factor);
|
||||
});
|
||||
|
||||
|
||||
47
simulator.js
47
simulator.js
@ -2,12 +2,15 @@ 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';
|
||||
|
||||
export class Sim {
|
||||
info = {};
|
||||
frame = 0;
|
||||
frameCount = 0;
|
||||
time = undefined;
|
||||
nextZoom = undefined;
|
||||
playing = true;
|
||||
|
||||
display = undefined;
|
||||
overlay = undefined;
|
||||
@ -23,6 +26,10 @@ export class Sim {
|
||||
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;
|
||||
@ -43,26 +50,38 @@ export class Sim {
|
||||
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;
|
||||
if (this.playing) {
|
||||
this.frameCount += 1;
|
||||
const elapsedTime = currentTime - this.time;
|
||||
this.time = currentTime;
|
||||
if (this.nextZoom) {
|
||||
this.zoom(this.nextZoom);
|
||||
this.nextZoom = undefined;
|
||||
}
|
||||
this.display.fillCanvas();
|
||||
this.objects.computeFrame(elapsedTime);
|
||||
|
||||
this.info['scale'] = this.display.scale;
|
||||
|
||||
this.display.drawObjects();
|
||||
this.overlay.renderInfo();
|
||||
}
|
||||
this.display.fillCanvas();
|
||||
this.objects.computeFrame(elapsedTime);
|
||||
|
||||
this.info['scale'] = this.display.scale;
|
||||
|
||||
this.display.drawObjects();
|
||||
this.overlay.renderInfo();
|
||||
|
||||
requestAnimationFrame(t => this.loop(t));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
20
tool.js
Normal file
20
tool.js
Normal file
@ -0,0 +1,20 @@
|
||||
// Idea here is, tool can declare its parameters;
|
||||
// can call back to toolbar for whatever...
|
||||
// through toolbar can access sim
|
||||
|
||||
export class Tool {
|
||||
toolbar = undefined;
|
||||
sim = undefined;
|
||||
|
||||
constructor(toolbar) {
|
||||
this.toolbar = toolbar;
|
||||
this.sim = this.toolbar.sim;
|
||||
const div = document.createElement('div');
|
||||
this.div = div;
|
||||
div.style.position = 'inline-block';
|
||||
div.style.border = '1px #0fb solid';
|
||||
div.style.margin = 10;
|
||||
}
|
||||
|
||||
frame() {}
|
||||
}
|
||||
30
toolbar.js
Normal file
30
toolbar.js
Normal file
@ -0,0 +1,30 @@
|
||||
export class Toolbar {
|
||||
sim = undefined;
|
||||
tools = [];
|
||||
|
||||
constructor(sim) {
|
||||
this.sim = sim;
|
||||
|
||||
// Create ourselves a div, as child of sim's div
|
||||
const div = document.createElement('div');
|
||||
this.div = div;
|
||||
this.sim.div.appendChild(div);
|
||||
div.style.position = 'absolute';
|
||||
div.style.top = 0;
|
||||
div.style.left = 0;
|
||||
div.style.zIndex = 2;
|
||||
}
|
||||
|
||||
// tool: instance of Tool
|
||||
addTool(tool) {
|
||||
this.div.appendChild(tool.div);
|
||||
this.tools.push(tool);
|
||||
}
|
||||
|
||||
frame() {
|
||||
for (let tool in this.tools) {
|
||||
// TODO: tool.frame()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
39
tools/play-pause.js
Normal file
39
tools/play-pause.js
Normal file
@ -0,0 +1,39 @@
|
||||
import { Tool } from '../tool.js';
|
||||
|
||||
export class PlayPause extends Tool {
|
||||
constructor(toolbar) {
|
||||
super(toolbar);
|
||||
|
||||
const playHTML = 'Play';
|
||||
const pauseHTML = 'Pause';
|
||||
|
||||
// For now, use a regular button
|
||||
const button = document.createElement('button');
|
||||
this.div.appendChild(button);
|
||||
if (this.playing) {
|
||||
button.innerHTML = pauseHTML;
|
||||
} else {
|
||||
button.innerHTML = playHTML;
|
||||
}
|
||||
button.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (this.playing) {
|
||||
button.innerHTML = playHTML;
|
||||
this.playing = false;
|
||||
} else {
|
||||
button.innerHTML = pauseHTML;
|
||||
this.playing = true;
|
||||
}
|
||||
});
|
||||
|
||||
console.log('PlayPause tool constructed ~!~');
|
||||
}
|
||||
|
||||
get playing() {
|
||||
return this.sim.playing;
|
||||
}
|
||||
|
||||
set playing(playing) {
|
||||
return this.sim.playing = playing;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user