Compare commits
3 Commits
e3fe7bd4e4
...
8cd706f910
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cd706f910 | ||
|
|
d8debf1a52 | ||
|
|
17c01a4bf4 |
@ -44,6 +44,8 @@ export const GRAVITATIONAL_CONSTANT = 1E5;
|
|||||||
|
|
||||||
// CSS CLASS NAMES
|
// CSS CLASS NAMES
|
||||||
export const DRAGGABLE_ELEMENT_CLASSNAME = 'lhg-draggable-element';
|
export const DRAGGABLE_ELEMENT_CLASSNAME = 'lhg-draggable-element';
|
||||||
|
export const TOOL_CLASSNAME = 'lhg-tool';
|
||||||
|
export const TOOLBAR_CLASSNAME = 'lhg-toolbar';
|
||||||
|
|
||||||
// EVENT NAMES
|
// EVENT NAMES
|
||||||
export const EVENT_MODE_LEAVE = 'lhg-mode-leave';
|
export const EVENT_MODE_LEAVE = 'lhg-mode-leave';
|
||||||
@ -52,6 +54,7 @@ export const EVENT_MODE_ENTER = 'lhg-mode-enter';
|
|||||||
// MODES
|
// MODES
|
||||||
export const MODE_MASS_GENERATION = 'mass-gen';
|
export const MODE_MASS_GENERATION = 'mass-gen';
|
||||||
export const MODE_PAN_VIEW = 'pan-view';
|
export const MODE_PAN_VIEW = 'pan-view';
|
||||||
|
export const MODE_OBJECT_SELECT = 'select';
|
||||||
|
|
||||||
// OPTIONS
|
// OPTIONS
|
||||||
export const PAUSE_DURING_CREATION = true;
|
export const PAUSE_DURING_CREATION = true;
|
||||||
|
|||||||
13
display.js
13
display.js
@ -106,18 +106,7 @@ export class Display {
|
|||||||
let dash = false;
|
let dash = false;
|
||||||
const skip = 1;
|
const skip = 1;
|
||||||
let skipped = 0;
|
let skipped = 0;
|
||||||
{
|
for (let i = obj.history.length - 1; i >= 0; i--) {
|
||||||
const [{position}] = obj.history;
|
|
||||||
const x = position.x;
|
|
||||||
const y = position.y;
|
|
||||||
|
|
||||||
if (Math.abs(x - cx) <= W / 2 &&
|
|
||||||
Math.abs(y - cy) <= H / 2) {
|
|
||||||
ctx.moveTo(x, y);
|
|
||||||
dash = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 1; i < obj.history.length; i++) {
|
|
||||||
if (++skipped < skip) continue;
|
if (++skipped < skip) continue;
|
||||||
skipped = 0;
|
skipped = 0;
|
||||||
const {position} = obj.history[i];
|
const {position} = obj.history[i];
|
||||||
|
|||||||
33
index.html
33
index.html
@ -15,7 +15,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div[id=simulator] {
|
div[id=simulator] {
|
||||||
position: float;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -23,16 +23,39 @@ div[id=simulator] {
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
width: 8em;
|
width: 8em;
|
||||||
padding-left: 0.5em;
|
border-radius: 0.5EM;
|
||||||
padding-right: 0.5em;
|
border-color: #000;
|
||||||
padding-top: 0;
|
border-width: 2px;
|
||||||
padding-bottom: 0;
|
/* margin-left: 0.5em; */
|
||||||
|
/* margin-right: 0.5em; */
|
||||||
|
/* padding-top: 0; */
|
||||||
|
/* padding-bottom: 0; */
|
||||||
}
|
}
|
||||||
|
|
||||||
button.wide {
|
button.wide {
|
||||||
width: 16em;
|
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>
|
</style>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { Sim } from './simulator.js';
|
import { Sim } from './simulator.js';
|
||||||
|
|||||||
@ -26,6 +26,8 @@ export class Sim {
|
|||||||
overlay = undefined;
|
overlay = undefined;
|
||||||
pointer = undefined;
|
pointer = undefined;
|
||||||
objects = undefined;
|
objects = undefined;
|
||||||
|
toolbar = undefined;
|
||||||
|
toolbar2 = undefined;
|
||||||
|
|
||||||
isCurrentMode = () => false;
|
isCurrentMode = () => false;
|
||||||
getOption = () => undefined;
|
getOption = () => undefined;
|
||||||
@ -44,7 +46,10 @@ export class Sim {
|
|||||||
this.toolbar.addTool(new Zoom(this.toolbar));
|
this.toolbar.addTool(new Zoom(this.toolbar));
|
||||||
this.toolbar.addTool(new PlayPause(this.toolbar));
|
this.toolbar.addTool(new PlayPause(this.toolbar));
|
||||||
this.toolbar.addTool(new ModeSwitch(this.toolbar));
|
this.toolbar.addTool(new ModeSwitch(this.toolbar));
|
||||||
this.toolbar.addTool(new Options(this.toolbar));
|
|
||||||
|
// Set up second toolbar
|
||||||
|
this.toolbar2 = new Toolbar(this).topRight();
|
||||||
|
this.toolbar2.addTool(new Options(this.toolbar));
|
||||||
|
|
||||||
this.pointer = new Pointer(this);
|
this.pointer = new Pointer(this);
|
||||||
|
|
||||||
|
|||||||
12
tool.js
12
tool.js
@ -2,7 +2,10 @@
|
|||||||
// can call back to toolbar for whatever...
|
// can call back to toolbar for whatever...
|
||||||
// through toolbar can access sim
|
// through toolbar can access sim
|
||||||
|
|
||||||
import {DRAGGABLE_ELEMENT_CLASSNAME} from './config.js';
|
import {
|
||||||
|
DRAGGABLE_ELEMENT_CLASSNAME,
|
||||||
|
TOOL_CLASSNAME,
|
||||||
|
} from './config.js';
|
||||||
|
|
||||||
export class Tool {
|
export class Tool {
|
||||||
toolbar = undefined;
|
toolbar = undefined;
|
||||||
@ -13,12 +16,7 @@ export class Tool {
|
|||||||
this.sim = this.toolbar.sim;
|
this.sim = this.toolbar.sim;
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
this.div = div;
|
this.div = div;
|
||||||
div.style.position = 'relative';
|
div.classList.add(TOOL_CLASSNAME)
|
||||||
div.style.top = 0;
|
|
||||||
div.style.left = 0;
|
|
||||||
div.style.border = '1px #0fb solid';
|
|
||||||
div.style.margin = '25px';
|
|
||||||
div.style.padding = '25px';
|
|
||||||
div.classList.add(DRAGGABLE_ELEMENT_CLASSNAME);
|
div.classList.add(DRAGGABLE_ELEMENT_CLASSNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { Tool } from '../tool.js';
|
|||||||
import {
|
import {
|
||||||
MODE_MASS_GENERATION,
|
MODE_MASS_GENERATION,
|
||||||
MODE_PAN_VIEW,
|
MODE_PAN_VIEW,
|
||||||
|
MODE_OBJECT_SELECT,
|
||||||
EVENT_MODE_LEAVE,
|
EVENT_MODE_LEAVE,
|
||||||
EVENT_MODE_ENTER,
|
EVENT_MODE_ENTER,
|
||||||
} from '../config.js';
|
} from '../config.js';
|
||||||
@ -12,6 +13,7 @@ export class ModeSwitch extends Tool {
|
|||||||
modes = [
|
modes = [
|
||||||
[MODE_MASS_GENERATION, 'Generate Mass'],
|
[MODE_MASS_GENERATION, 'Generate Mass'],
|
||||||
[MODE_PAN_VIEW, 'Pan View'],
|
[MODE_PAN_VIEW, 'Pan View'],
|
||||||
|
[MODE_OBJECT_SELECT, 'Select'],
|
||||||
];
|
];
|
||||||
buttons = [];
|
buttons = [];
|
||||||
|
|
||||||
@ -19,16 +21,9 @@ export class ModeSwitch extends Tool {
|
|||||||
super(toolbar);
|
super(toolbar);
|
||||||
|
|
||||||
const modesDiv = document.createElement('div');
|
const modesDiv = document.createElement('div');
|
||||||
const titleDiv = document.createElement('div');
|
|
||||||
|
|
||||||
this.div.appendChild(titleDiv);
|
|
||||||
this.div.appendChild(modesDiv);
|
this.div.appendChild(modesDiv);
|
||||||
|
|
||||||
titleDiv.innerHTML = `<h2>Modes</h2>`;
|
|
||||||
|
|
||||||
// Since we have a heading, we need to reduce top padding
|
|
||||||
this.div.style.paddingTop = '0px';
|
|
||||||
|
|
||||||
modesDiv.style.display = 'flex';
|
modesDiv.style.display = 'flex';
|
||||||
modesDiv.style.flexDirection = 'column';
|
modesDiv.style.flexDirection = 'column';
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
|
|
||||||
export class Options extends Tool {
|
export class Options extends Tool {
|
||||||
options = [{
|
options = [{
|
||||||
type: 'group', name: 'pauseDuring', title: 'Pause During',
|
type: 'group', name: 'pauseDuring', title: 'Pause During Mass',
|
||||||
items: [
|
items: [
|
||||||
{ type: 'boolean', name: 'creation', title: 'Creation', default: PAUSE_DURING_CREATION },
|
{ type: 'boolean', name: 'creation', title: 'Creation', default: PAUSE_DURING_CREATION },
|
||||||
{ type: 'boolean', name: 'selection', title: 'Selection', default: PAUSE_DURING_SELECTION },
|
{ type: 'boolean', name: 'selection', title: 'Selection', default: PAUSE_DURING_SELECTION },
|
||||||
@ -19,11 +19,11 @@ export class Options extends Tool {
|
|||||||
items: [
|
items: [
|
||||||
{ type: 'boolean', name: 'velocity', title: 'Velocity', default: DISPLAY_VELOCITY_VECTORS },
|
{ 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: 'Acceleration', default: DISPLAY_ACCELERATION_VECTORS },
|
||||||
{ type: 'boolean', name: 'traces', title: 'Trace Path', default: DISPLAY_ACCELERATION_VECTORS },
|
{ type: 'boolean', name: 'traces', title: 'Path Traces', default: DISPLAY_ACCELERATION_VECTORS , wide: true},
|
||||||
]}, {
|
]}, {
|
||||||
type: 'group', name: 'collision', title: 'Collisions',
|
type: 'group', name: 'collision', title: 'Collision',
|
||||||
items: [
|
items: [
|
||||||
{ type: 'boolean', name: 'merge', title: 'Merge', default: MERGE_ON_COLLIDE },
|
{ type: 'boolean', name: 'merge', title: 'Merge Masses', default: MERGE_ON_COLLIDE, wide: true},
|
||||||
]},
|
]},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -46,6 +46,9 @@ export class Options extends Tool {
|
|||||||
case 'boolean': {
|
case 'boolean': {
|
||||||
const button = document.createElement('button');
|
const button = document.createElement('button');
|
||||||
button.innerHTML = `<h4>${item.title}</h4>`;
|
button.innerHTML = `<h4>${item.title}</h4>`;
|
||||||
|
if (item.wide === true) {
|
||||||
|
button.classList.add('wide');
|
||||||
|
}
|
||||||
this.setOption(path, item.default);
|
this.setOption(path, item.default);
|
||||||
button.style.opacity = this.values[path] ? '100%' : '50%';
|
button.style.opacity = this.values[path] ? '100%' : '50%';
|
||||||
button.addEventListener('click', () => {
|
button.addEventListener('click', () => {
|
||||||
@ -64,7 +67,6 @@ export class Options extends Tool {
|
|||||||
const heading = document.createElement('h2');
|
const heading = document.createElement('h2');
|
||||||
heading.innerHTML = 'Options';
|
heading.innerHTML = 'Options';
|
||||||
this.div.appendChild(heading);
|
this.div.appendChild(heading);
|
||||||
this.div.style.paddingTop = '0px';
|
|
||||||
for (const item of this.options) {
|
for (const item of this.options) {
|
||||||
const child = this.visitItem(item);
|
const child = this.visitItem(item);
|
||||||
this.div.appendChild(child);
|
this.div.appendChild(child);
|
||||||
|
|||||||
@ -46,7 +46,7 @@ export class Zoom extends Tool {
|
|||||||
const widthRatio = Math.abs(box.start.x - box.end.x) / this.sim.display.width;
|
const widthRatio = Math.abs(box.start.x - box.end.x) / this.sim.display.width;
|
||||||
const heightRatio = Math.abs(box.start.y - box.end.y) / this.sim.display.height;
|
const heightRatio = Math.abs(box.start.y - box.end.y) / this.sim.display.height;
|
||||||
const biggerRatio = Math.max(widthRatio, heightRatio);
|
const biggerRatio = Math.max(widthRatio, heightRatio);
|
||||||
const base2factor = Math.log(1/biggerRatio) / Math.log(2) - 0.5;
|
const base2factor = Math.log(1/biggerRatio) / Math.log(2) - 1;
|
||||||
const factor = Math.floor(base2factor);
|
const factor = Math.floor(base2factor);
|
||||||
// Determine average momentum and set panning velocity to match
|
// Determine average momentum and set panning velocity to match
|
||||||
const netMomentum = {x: 0, y: 0};
|
const netMomentum = {x: 0, y: 0};
|
||||||
|
|||||||
16
toolbar.js
16
toolbar.js
@ -1,3 +1,7 @@
|
|||||||
|
import {
|
||||||
|
TOOLBAR_CLASSNAME,
|
||||||
|
} from './config.js';
|
||||||
|
|
||||||
export class Toolbar {
|
export class Toolbar {
|
||||||
sim = undefined;
|
sim = undefined;
|
||||||
tools = [];
|
tools = [];
|
||||||
@ -9,11 +13,13 @@ export class Toolbar {
|
|||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
this.div = div;
|
this.div = div;
|
||||||
this.sim.div.appendChild(div);
|
this.sim.div.appendChild(div);
|
||||||
div.style.position = 'relative';
|
div.classList.add(TOOLBAR_CLASSNAME);
|
||||||
div.style.width = '20EM';
|
}
|
||||||
div.style.top = 0;
|
|
||||||
div.style.left = 0;
|
topRight() {
|
||||||
div.style.zIndex = 2;
|
this.div.style.top = '0px';
|
||||||
|
this.div.style.right = '0px';
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tool: instance of Tool
|
// tool: instance of Tool
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user