collapsable toolbars
This commit is contained in:
parent
54868aeba8
commit
a6eda0226b
@ -2,7 +2,7 @@
|
||||
export const DISPLAY_OBJECTS_INFO = false;
|
||||
export const DISPLAY_CURSOR_INFO = false;
|
||||
export const DISPLAY_CANVAS_SIZE = false;
|
||||
export const DISPLAY_CURRENT_SCALE = true;
|
||||
export const DISPLAY_CURRENT_SCALE = false;
|
||||
export const DISPLAY_CURRENT_MODE = false;
|
||||
export const DISPLAY_VELOCITY_VECTORS = true;
|
||||
export const DISPLAY_ACCELERATION_VECTORS = true;
|
||||
@ -21,7 +21,6 @@ export const ACCELERATION_VECTOR_WIDTH = 1.5;
|
||||
export const ACCELERATION_VECTOR_ARROWHEAD = true;
|
||||
|
||||
// PATH TRACES
|
||||
// export const PATH_TRACES_COLOR = 'rgb(128, 128, 0)'; // optionally set to 'object color'
|
||||
export const PATH_TRACES_COLOR = 'object color';
|
||||
export const PATH_TRACES_OPACITY = 0.8;
|
||||
export const PATH_TRACES_WIDTH = 1.5;
|
||||
@ -46,13 +45,15 @@ export const SCALE_POWER_MIN = -8;
|
||||
export const GRAVITATIONAL_CONSTANT = 1E5;
|
||||
|
||||
// CSS CLASS NAMES
|
||||
export const DRAGGABLE_ELEMENT_CLASSNAME = 'lhg-draggable-element';
|
||||
export const TOOL_CLASSNAME = 'lhg-tool';
|
||||
export const TOOL_INFO_CLASSNAME = 'lhg-tool-info';
|
||||
export const TOOLBAR_CLASSNAME = 'lhg-toolbar';
|
||||
export const WIDE_CLASSNAME = 'lhg-wide';
|
||||
|
||||
// EVENT NAMES
|
||||
export const EVENT_MODE_LEAVE = 'lhg-mode-leave';
|
||||
export const EVENT_MODE_ENTER = 'lhg-mode-enter';
|
||||
export const EVENT_ZOOM = 'lhg-zoom-event';
|
||||
|
||||
// MODES
|
||||
export const MODE_MASS_GENERATION = 'mass-gen';
|
||||
|
||||
55
index.html
55
index.html
@ -3,60 +3,7 @@
|
||||
<head>
|
||||
<title>Gravity Simulator</title>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<style>
|
||||
body {
|
||||
background-color: #000;
|
||||
color: #8f8;
|
||||
font-family: monospace;
|
||||
font-size: 12pt;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
div[id=simulator] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 8em;
|
||||
border-radius: 0.5EM;
|
||||
border-color: #000;
|
||||
border-width: 2px;
|
||||
/* margin-left: 0.5em; */
|
||||
/* margin-right: 0.5em; */
|
||||
/* padding-top: 0; */
|
||||
/* padding-bottom: 0; */
|
||||
}
|
||||
|
||||
button.wide {
|
||||
width: 16em;
|
||||
}
|
||||
|
||||
div.lhg-tool {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 14EM;
|
||||
|
||||
/* border: 1px #0fb solid; */
|
||||
/* margin: 1EM; */
|
||||
padding: 1EM;
|
||||
}
|
||||
|
||||
div.lhg-toolbar {
|
||||
position: fixed;
|
||||
z-index: 2;
|
||||
width: fit-content;
|
||||
/* border: 2px #00f dashed; */
|
||||
/* margin: '1EM'; */
|
||||
/* padding: '1EM'; */
|
||||
}
|
||||
|
||||
</style>
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
<script type="module">
|
||||
import { Sim } from './simulator.js';
|
||||
const sim = new Sim('simulator');
|
||||
|
||||
24
overlay.js
24
overlay.js
@ -1,5 +1,3 @@
|
||||
import {DRAGGABLE_ELEMENT_CLASSNAME} from './config.js';
|
||||
|
||||
export class Overlay {
|
||||
sim = undefined;
|
||||
constructor(sim) {
|
||||
@ -12,10 +10,9 @@ export class Overlay {
|
||||
infoBox.style.position = 'relative';
|
||||
infoBox.style.display = 'inline-block';
|
||||
infoBox.style.top = 0;
|
||||
infoBox.style.left = 0;
|
||||
infoBox.style.left = '14em';
|
||||
infoBox.width = 'fit-content';
|
||||
infoBox.style.zIndex = 1;
|
||||
infoBox.classList.add(DRAGGABLE_ELEMENT_CLASSNAME);
|
||||
}
|
||||
|
||||
renderInfo() {
|
||||
@ -36,23 +33,4 @@ export class Overlay {
|
||||
}
|
||||
this.infoBox.appendChild(table);
|
||||
}
|
||||
|
||||
// Update positions of draggable items
|
||||
updateDraggable() {
|
||||
const elements = document.querySelectorAll(`.${DRAGGABLE_ELEMENT_CLASSNAME}`);
|
||||
for (let el of elements) {
|
||||
if (!el.dragging) continue;
|
||||
const {
|
||||
elementStart: {x: x0, y: y0},
|
||||
pointerStart: {x: x1, y: y1},
|
||||
pointerEnd: {x: x2, y: y2}
|
||||
} = el.dragging;
|
||||
const dx = x2 - x1;
|
||||
const dy = y2 - y1;
|
||||
const left = x0 + dx;
|
||||
const top = y0 + dy;
|
||||
el.style.left = `${left}px`;
|
||||
el.style.top = `${top}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
45
pointer.js
45
pointer.js
@ -1,6 +1,5 @@
|
||||
import {
|
||||
DISPLAY_CURSOR_INFO,
|
||||
DRAGGABLE_ELEMENT_CLASSNAME,
|
||||
MODE_MASS_GENERATION,
|
||||
MODE_OBJECT_SELECT,
|
||||
MODE_PAN_VIEW,
|
||||
@ -13,7 +12,6 @@ export class Pointer {
|
||||
sim = undefined;
|
||||
|
||||
pointerHistory = [];
|
||||
draggingElement = undefined;
|
||||
panning = undefined; // { velocity: {x and y in sim coordinates}, paused: boolean }
|
||||
panTouchStart = undefined; // {x: undefined, y: undefined, t: undefined};
|
||||
panTouchLatest = undefined; // {x: undefined, y: undefined, t: undefined};
|
||||
@ -29,53 +27,20 @@ export class Pointer {
|
||||
if (DISPLAY_CURSOR_INFO) {
|
||||
this.sim.info['pointermove'] = [`${e.clientX}, `, `${e.clientY}`];
|
||||
}
|
||||
|
||||
if (this.draggingElement) {
|
||||
this.draggingElement.dragging.pointerEnd = {
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
};
|
||||
} else {
|
||||
this.handlePointerMove({x: e.clientX, y: e.clientY});
|
||||
}
|
||||
this.handlePointerMove({x: e.clientX, y: e.clientY});
|
||||
});
|
||||
|
||||
el.addEventListener('pointerdown', e => {
|
||||
// If this is a child of a draggable element, handle dragging
|
||||
let target = e.target;
|
||||
while (target && !target.classList.contains(DRAGGABLE_ELEMENT_CLASSNAME)) {
|
||||
target = target.parentElement;
|
||||
if (target.nodeName.toLowerCase() === 'button') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target?.classList.contains(DRAGGABLE_ELEMENT_CLASSNAME)) {
|
||||
this.draggingElement = target;
|
||||
this.draggingElement.dragging = {
|
||||
elementStart: {
|
||||
x: parseInt(this.draggingElement.style.left),
|
||||
y: parseInt(this.draggingElement.style.top),
|
||||
},
|
||||
pointerStart: {
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
},
|
||||
pointerEnd: {
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
this.handlePointerDown({x: e.clientX, y: e.clientY});
|
||||
}
|
||||
this.handlePointerDown({x: e.clientX, y: e.clientY});
|
||||
});
|
||||
|
||||
el.addEventListener('pointerup', e => {
|
||||
if (this.draggingElement) {
|
||||
this.draggingElement.dragging = undefined;
|
||||
this.draggingElement = undefined;
|
||||
this.lastPosition = {x: undefined, y: undefined};
|
||||
} else {
|
||||
this.handlePointerUp({x: e.clientX, y: e.clientY});
|
||||
}
|
||||
this.handlePointerUp({x: e.clientX, y: e.clientY});
|
||||
});
|
||||
|
||||
// Monitor wheel events
|
||||
|
||||
29
simulator.js
29
simulator.js
@ -13,6 +13,7 @@ import {
|
||||
DISPLAY_CURRENT_SCALE,
|
||||
DISPLAY_CURRENT_MODE,
|
||||
MOTION_TIME_SCALE,
|
||||
EVENT_ZOOM,
|
||||
} from './config.js';
|
||||
|
||||
export class Sim {
|
||||
@ -41,9 +42,10 @@ export class Sim {
|
||||
this.div = div;
|
||||
|
||||
this.display = new Display(this);
|
||||
this.overlay = new Overlay(this);
|
||||
this.objects = new Objects(this);
|
||||
this.toolbar = new Toolbar(this);
|
||||
this.toolbar = new Toolbar(this, 'Tools');
|
||||
this.toolbar2 = new Toolbar(this, 'Options');
|
||||
this.overlay = new Overlay(this);
|
||||
|
||||
// Set up toolbar
|
||||
this.toolbar.addTool(new Zoom(this.toolbar));
|
||||
@ -51,7 +53,7 @@ export class Sim {
|
||||
this.toolbar.addTool(new ModeSwitch(this.toolbar));
|
||||
|
||||
// Set up second toolbar
|
||||
this.toolbar2 = new Toolbar(this).topRight();
|
||||
this.toolbar2.topRight();
|
||||
this.toolbar2.addTool(new Options(this.toolbar));
|
||||
|
||||
this.pointer = new Pointer(this);
|
||||
@ -92,6 +94,9 @@ export class Sim {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const e = new CustomEvent(EVENT_ZOOM);
|
||||
this.div.dispatchEvent(e);
|
||||
}
|
||||
|
||||
// Transform display coordinates to simulator coordinates using scale and viewOrigin
|
||||
@ -107,6 +112,18 @@ export class Sim {
|
||||
this.playing = false;
|
||||
}
|
||||
|
||||
getScaleDisplay() {
|
||||
const scale = 2 ** Math.abs(this.display.scalePower);
|
||||
return this.display.scalePower >= 0 ? `${scale}` : `1/${scale}`;
|
||||
}
|
||||
|
||||
// cb: () => undefined
|
||||
onZoom(cb) {
|
||||
this.div.addEventListener(EVENT_ZOOM, () => {
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
// Main loop
|
||||
loop(currentTime) {
|
||||
const elapsedTime = (currentTime - this.time) * MOTION_TIME_SCALE;
|
||||
@ -122,16 +139,12 @@ export class Sim {
|
||||
}
|
||||
|
||||
if (DISPLAY_CURRENT_SCALE) {
|
||||
const scale = 2 ** Math.abs(this.display.scalePower);
|
||||
this.info['Scale'] = this.display.scalePower >= 0 ? `${scale}` : `1/${scale}`;
|
||||
this.info['Scale'] = this.getScaleDisplay();
|
||||
}
|
||||
|
||||
this.pointer.computeFrame(elapsedTime);
|
||||
this.objects.computeFrame(elapsedTime);
|
||||
|
||||
this.overlay.updateDraggable();
|
||||
this.overlay.renderInfo();
|
||||
|
||||
this.display.fillCanvas();
|
||||
this.display.drawObjects();
|
||||
|
||||
|
||||
91
style.css
Normal file
91
style.css
Normal file
@ -0,0 +1,91 @@
|
||||
body {
|
||||
background-color: #000;
|
||||
color: #5f5;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-block-start: 4pt;
|
||||
margin-block-end: 4pt;
|
||||
text-align: center;
|
||||
font-size: 12pt;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 16pt;
|
||||
}
|
||||
|
||||
div[id=simulator] {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.lhg-toolbar {
|
||||
position: fixed;
|
||||
z-index: 2;
|
||||
width: fit-content;
|
||||
border-radius: 0.5EM;
|
||||
}
|
||||
|
||||
div.lhg-toolbar div.lhg-tool {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 12EM;
|
||||
padding: 0.5EM;
|
||||
margin: 0.5EM;
|
||||
border-radius: 0.5EM;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #282;
|
||||
}
|
||||
|
||||
div.lhg-tool button {
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
width: 6em;
|
||||
background-color: #333;
|
||||
color: #5f5;
|
||||
border-radius: 0.5EM;
|
||||
border-color: #000;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
padding-top: 0.5EM;
|
||||
padding-bottom: 0.5EM;
|
||||
padding-left: 0EM;
|
||||
padding-right: 0EM;
|
||||
text-align: center;
|
||||
/* margin-top: 0.125EM;
|
||||
margin-bottom: 0.125EM; */
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
div.lhg-tool button:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
div.lhg-tool button:active {
|
||||
background-color: #252;
|
||||
}
|
||||
|
||||
div.lhg-tool button.lhg-tool-info {
|
||||
background-color: #111;
|
||||
border-color: #282;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
div.lhg-tool button.lhg-wide {
|
||||
width: 12em;
|
||||
}
|
||||
|
||||
div.lhg-tool > div {
|
||||
/* border: 2px red solid; */
|
||||
}
|
||||
14
sync
14
sync
@ -5,8 +5,18 @@ if [[ $(hostname) != "ladd76" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rsync -ru --exclude='.git' --exclude='node_modules' ~/code/gravity-dev/ lentilz:code/gravity-dev/
|
||||
rsync -ru --exclude='.git' --exclude='node_modules' lentilz:code/gravity-dev/ ~/code/gravity-dev/
|
||||
set -eo pipefail
|
||||
|
||||
do_rsync() {
|
||||
rsync -ru \
|
||||
--exclude='.git' \
|
||||
--exclude='node_modules' \
|
||||
--exclude='.*.sw*' \
|
||||
"$@"
|
||||
}
|
||||
|
||||
do_rsync ~/code/gravity-dev/ lentilz:code/gravity-dev/
|
||||
do_rsync lentilz:code/gravity-dev/ ~/code/gravity-dev/
|
||||
|
||||
echo >&2
|
||||
echo >&2 "Synced with https://laddhoffman.com/gravity-dev/"
|
||||
|
||||
2
tool.js
2
tool.js
@ -3,7 +3,6 @@
|
||||
// through toolbar can access sim
|
||||
|
||||
import {
|
||||
DRAGGABLE_ELEMENT_CLASSNAME,
|
||||
TOOL_CLASSNAME,
|
||||
} from './config.js';
|
||||
|
||||
@ -17,7 +16,6 @@ export class Tool {
|
||||
const div = document.createElement('div');
|
||||
this.div = div;
|
||||
div.classList.add(TOOL_CLASSNAME)
|
||||
div.classList.add(DRAGGABLE_ELEMENT_CLASSNAME);
|
||||
}
|
||||
|
||||
frame() {}
|
||||
|
||||
49
tool/header.js
Normal file
49
tool/header.js
Normal file
@ -0,0 +1,49 @@
|
||||
import { Tool } from '../tool.js';
|
||||
|
||||
export class Header extends Tool {
|
||||
expanded = true;
|
||||
|
||||
constructor(toolbar, title = 'Tools') {
|
||||
super(toolbar);
|
||||
|
||||
this.title = document.createElement('h1');
|
||||
this.title.innerHTML = title;
|
||||
|
||||
this.toggleButton = document.createElement('button');
|
||||
this.updateButton();
|
||||
this.toggleButton.addEventListener('click', () => this.toggle());
|
||||
|
||||
this.div.appendChild(this.title);
|
||||
this.div.appendChild(this.toggleButton);
|
||||
|
||||
this.title.style.verticalAlign = 'center';
|
||||
this.toggleButton.style.width = '3EM';
|
||||
this.div.style.display = 'flex';
|
||||
this.div.style.justifyContent = 'space-around';
|
||||
}
|
||||
|
||||
updateButton() {
|
||||
this.toggleButton.innerHTML = this.expanded ? '˄' : '˅';
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.expanded = !this.expanded;
|
||||
this.updateButton();
|
||||
this.apply();
|
||||
}
|
||||
|
||||
apply() {
|
||||
for (const tool of this.toolbar.tools) {
|
||||
if (tool === this) continue;
|
||||
if (this.expanded) {
|
||||
if (!this.toolbar.div.contains(tool.div)) {
|
||||
this.toolbar.div.appendChild(tool.div);
|
||||
}
|
||||
} else {
|
||||
if (this.toolbar.div.contains(tool.div)) {
|
||||
this.toolbar.div.removeChild(tool.div);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import {
|
||||
MODE_OBJECT_SELECT,
|
||||
EVENT_MODE_LEAVE,
|
||||
EVENT_MODE_ENTER,
|
||||
WIDE_CLASSNAME,
|
||||
} from '../config.js';
|
||||
|
||||
export class ModeSwitch extends Tool {
|
||||
@ -21,7 +22,11 @@ export class ModeSwitch extends Tool {
|
||||
super(toolbar);
|
||||
|
||||
const modesDiv = document.createElement('div');
|
||||
const heading = document.createElement('h2');
|
||||
|
||||
heading.innerHTML = 'Modes';
|
||||
|
||||
// this.div.appendChild(heading);
|
||||
this.div.appendChild(modesDiv);
|
||||
|
||||
modesDiv.style.display = 'flex';
|
||||
@ -32,8 +37,8 @@ export class ModeSwitch extends Tool {
|
||||
this.buttons.push(button);
|
||||
button.modeID = modeID;
|
||||
modesDiv.appendChild(button);
|
||||
button.innerHTML = `<h3>${modeTitle}</h3>`;
|
||||
button.classList.add('wide');
|
||||
button.innerHTML = modeTitle;
|
||||
button.classList.add(WIDE_CLASSNAME);
|
||||
|
||||
button.addEventListener('click', () => this.setCurrentMode(modeID));
|
||||
}
|
||||
|
||||
@ -6,21 +6,22 @@ import {
|
||||
PATH_TRACES_DASHED,
|
||||
PAUSE_DURING_CREATION,
|
||||
PAUSE_DURING_SELECTION,
|
||||
WIDE_CLASSNAME,
|
||||
} from '../config.js';
|
||||
import {Tool} from '../tool.js';
|
||||
|
||||
export class Options extends Tool {
|
||||
options = [{
|
||||
type: 'group', name: 'pauseDuring', title: 'Pause During Mass',
|
||||
type: 'group', name: 'pauseDuring', title: 'Pause During',
|
||||
items: [
|
||||
{type: 'boolean', name: 'creation', title: 'Creation', default: PAUSE_DURING_CREATION},
|
||||
{type: 'boolean', name: 'selection', title: 'Selection', default: PAUSE_DURING_SELECTION},
|
||||
{type: 'boolean', name: 'creation', title: 'Create', default: PAUSE_DURING_CREATION},
|
||||
{type: 'boolean', name: 'selection', title: 'Select', default: PAUSE_DURING_SELECTION},
|
||||
]
|
||||
}, {
|
||||
type: 'group', name: 'display', title: 'Display',
|
||||
items: [
|
||||
{type: 'boolean', name: 'velocity', title: 'Velocity', default: DISPLAY_VELOCITY_VECTORS},
|
||||
{type: 'boolean', name: 'acceleration', title: 'Acceleration', default: DISPLAY_ACCELERATION_VECTORS},
|
||||
{type: 'boolean', name: 'acceleration', title: 'Accel', default: DISPLAY_ACCELERATION_VECTORS},
|
||||
{type: 'boolean', name: 'traces', title: 'Traces', default: DISPLAY_ACCELERATION_VECTORS},
|
||||
{type: 'boolean', name: 'dashedTraces', title: 'Dashed', default: PATH_TRACES_DASHED},
|
||||
]
|
||||
@ -29,8 +30,7 @@ export class Options extends Tool {
|
||||
items: [
|
||||
{type: 'boolean', name: 'merge', title: 'Merge Masses', default: MERGE_ON_COLLIDE, wide: true},
|
||||
]
|
||||
},
|
||||
];
|
||||
}];
|
||||
|
||||
values = {};
|
||||
|
||||
@ -50,9 +50,9 @@ export class Options extends Tool {
|
||||
}
|
||||
case 'boolean': {
|
||||
const button = document.createElement('button');
|
||||
button.innerHTML = `<h4>${item.title}</h4>`;
|
||||
button.innerHTML = item.title;
|
||||
if (item.wide === true) {
|
||||
button.classList.add('wide');
|
||||
button.classList.add(WIDE_CLASSNAME);
|
||||
}
|
||||
this.setOption(path, item.default);
|
||||
button.style.opacity = this.values[path] ? '100%' : '50%';
|
||||
@ -71,7 +71,7 @@ export class Options extends Tool {
|
||||
super(toolbar);
|
||||
const heading = document.createElement('h2');
|
||||
heading.innerHTML = 'Options';
|
||||
this.div.appendChild(heading);
|
||||
// this.div.appendChild(heading);
|
||||
for (const item of this.options) {
|
||||
const child = this.visitItem(item);
|
||||
this.div.appendChild(child);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Tool } from '../tool.js';
|
||||
|
||||
export class PlayPause extends Tool {
|
||||
playHTML = '<h2>Play</h2>';
|
||||
pauseHTML = '<h2>Pause</h2>';
|
||||
playHTML = 'Play';
|
||||
pauseHTML = 'Pause';
|
||||
|
||||
constructor(toolbar) {
|
||||
super(toolbar);
|
||||
|
||||
21
tool/zoom.js
21
tool/zoom.js
@ -1,5 +1,7 @@
|
||||
import { Tool } from '../tool.js';
|
||||
import {
|
||||
TOOL_INFO_CLASSNAME,
|
||||
WIDE_CLASSNAME,
|
||||
ZOOM_IN_FACTOR,
|
||||
ZOOM_OUT_FACTOR,
|
||||
} from '../config.js';
|
||||
@ -8,21 +10,28 @@ export class Zoom extends Tool {
|
||||
constructor(toolbar) {
|
||||
super(toolbar);
|
||||
|
||||
const currentScale = document.createElement('button')
|
||||
const zoomOut = document.createElement('button');
|
||||
const zoomIn = document.createElement('button');
|
||||
const zoomAll = document.createElement('button');
|
||||
|
||||
this.div.appendChild(currentScale);
|
||||
this.div.appendChild(zoomOut);
|
||||
this.div.appendChild(zoomIn);
|
||||
this.div.appendChild(document.createElement('br'));
|
||||
this.div.appendChild(zoomAll);
|
||||
this.div.appendChild(document.createElement('br'));
|
||||
|
||||
zoomAll.classList.add('wide');
|
||||
zoomAll.classList.add(WIDE_CLASSNAME);
|
||||
currentScale.classList.add(WIDE_CLASSNAME);
|
||||
currentScale.classList.add(TOOL_INFO_CLASSNAME);
|
||||
|
||||
zoomOut.innerHTML = '<h2>Zoom<br>Out</h2>';
|
||||
zoomIn.innerHTML = '<h2>Zoom<br>In</h2>';
|
||||
zoomAll.innerHTML = '<h2>Zoom to Fit</h2>';
|
||||
zoomOut.innerHTML = 'Zoom<br>Out';
|
||||
zoomIn.innerHTML = 'Zoom<br>In';
|
||||
zoomAll.innerHTML = 'Zoom to Fit';
|
||||
currentScale.innerHTML = `Scale: ${this.sim.getScaleDisplay()}`;
|
||||
|
||||
this.sim.onZoom(() => {
|
||||
currentScale.innerHTML = `Scale: ${this.sim.getScaleDisplay()}`;
|
||||
});
|
||||
|
||||
zoomOut.addEventListener('click', () => {
|
||||
// Aim at center of view
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import {
|
||||
TOOLBAR_CLASSNAME,
|
||||
} from './config.js';
|
||||
import {Header} from './tool/header.js';
|
||||
|
||||
export class Toolbar {
|
||||
sim = undefined;
|
||||
tools = [];
|
||||
|
||||
constructor(sim) {
|
||||
constructor(sim, title) {
|
||||
this.sim = sim;
|
||||
|
||||
// Create ourselves a div, as child of sim's div
|
||||
@ -14,6 +15,10 @@ export class Toolbar {
|
||||
this.div = div;
|
||||
this.sim.div.appendChild(div);
|
||||
div.classList.add(TOOLBAR_CLASSNAME);
|
||||
|
||||
// Create a collapse/expand tool
|
||||
const header = new Header(this, title);
|
||||
this.addTool(header);
|
||||
}
|
||||
|
||||
topRight() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user