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_SCALE = 5;
|
||||||
export const OFFSCREEN_OBJECT_LINE_WIDTH = 1.5;
|
export const OFFSCREEN_OBJECT_LINE_WIDTH = 1.5;
|
||||||
export const OFFSCREEN_OBJECT_ARROWHEAD_LENGTH = 15;
|
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] {
|
div[id=simulator] {
|
||||||
position: absolute;
|
position: float;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
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 {
|
export class Pointer {
|
||||||
sim = undefined;
|
sim = undefined;
|
||||||
@ -11,30 +15,36 @@ export class Pointer {
|
|||||||
// Monitor mouse movements
|
// Monitor mouse movements
|
||||||
const el = window;
|
const el = window;
|
||||||
el.addEventListener('mousemove', e => {
|
el.addEventListener('mousemove', e => {
|
||||||
|
// e.preventDefault();
|
||||||
this.handlePointerMove(this.sim.screenToSim(e.clientX, e.clientY));
|
this.handlePointerMove(this.sim.screenToSim(e.clientX, e.clientY));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Monitor touch events
|
// Monitor touch events
|
||||||
el.addEventListener('touchmove', e => {
|
el.addEventListener('touchmove', e => {
|
||||||
|
// e.preventDefault();
|
||||||
const {pageX, pageY} = e.touches[0];
|
const {pageX, pageY} = e.touches[0];
|
||||||
this.handlePointerMove(this.sim.screenToSim(pageX, pageY));
|
this.handlePointerMove(this.sim.screenToSim(pageX, pageY));
|
||||||
});
|
});
|
||||||
|
|
||||||
el.addEventListener('pointerdown', e => {
|
el.addEventListener('pointerdown', e => {
|
||||||
|
// e.preventDefault();
|
||||||
this.handlePointerDown(this.sim.screenToSim(e.clientX, e.clientY));
|
this.handlePointerDown(this.sim.screenToSim(e.clientX, e.clientY));
|
||||||
});
|
});
|
||||||
|
|
||||||
el.addEventListener('pointerup', e => {
|
el.addEventListener('pointerup', e => {
|
||||||
|
// e.preventDefault();
|
||||||
this.handlePointerUp(this.sim.screenToSim(e.clientX, e.clientY));
|
this.handlePointerUp(this.sim.screenToSim(e.clientX, e.clientY));
|
||||||
});
|
});
|
||||||
|
|
||||||
el.addEventListener('click', e => {
|
el.addEventListener('click', e => {
|
||||||
|
// e.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Monitor wheel events
|
// Monitor wheel events
|
||||||
el.addEventListener('wheel', e => {
|
el.addEventListener('wheel', e => {
|
||||||
|
// e.preventDefault();
|
||||||
// Wheel scroll down => positive deltaY => ZOOM IN
|
// 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);
|
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 { Overlay } from './overlay.js';
|
||||||
import { Pointer } from './pointer.js';
|
import { Pointer } from './pointer.js';
|
||||||
import { Objects } from './objects.js';
|
import { Objects } from './objects.js';
|
||||||
|
import { Toolbar } from './toolbar.js';
|
||||||
|
import { PlayPause } from './tools/play-pause.js';
|
||||||
|
|
||||||
export class Sim {
|
export class Sim {
|
||||||
info = {};
|
info = {};
|
||||||
frame = 0;
|
frameCount = 0;
|
||||||
time = undefined;
|
time = undefined;
|
||||||
nextZoom = undefined;
|
nextZoom = undefined;
|
||||||
|
playing = true;
|
||||||
|
|
||||||
display = undefined;
|
display = undefined;
|
||||||
overlay = undefined;
|
overlay = undefined;
|
||||||
@ -23,6 +26,10 @@ export class Sim {
|
|||||||
this.overlay = new Overlay(this);
|
this.overlay = new Overlay(this);
|
||||||
this.pointer = new Pointer(this);
|
this.pointer = new Pointer(this);
|
||||||
this.objects = new Objects(this);
|
this.objects = new Objects(this);
|
||||||
|
this.toolbar = new Toolbar(this);
|
||||||
|
|
||||||
|
// Set up toolbar
|
||||||
|
this.toolbar.addTool(new PlayPause(this.toolbar));
|
||||||
|
|
||||||
// Initiate main loop
|
// Initiate main loop
|
||||||
this.time = document.timeline.currentTime;
|
this.time = document.timeline.currentTime;
|
||||||
@ -43,26 +50,38 @@ export class Sim {
|
|||||||
this.display.viewOrigin.y = y - this.display.height / 2;
|
this.display.viewOrigin.y = y - this.display.height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform display coordinates to simulator coordinates using scale and viewOrigin
|
||||||
screenToSim(x, y) {
|
screenToSim(x, y) {
|
||||||
return this.display.screenToSim(x, y);
|
return this.display.screenToSim(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
play() {
|
||||||
|
this.playing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
this.playing = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
loop(currentTime) {
|
loop(currentTime) {
|
||||||
const elapsedTime = currentTime - this.time;
|
if (this.playing) {
|
||||||
this.time = currentTime;
|
this.frameCount += 1;
|
||||||
if (this.nextZoom) {
|
const elapsedTime = currentTime - this.time;
|
||||||
this.zoom(this.nextZoom);
|
this.time = currentTime;
|
||||||
this.nextZoom = undefined;
|
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));
|
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