better spawning
This commit is contained in:
parent
27b68dccec
commit
145730434d
62
package-lock.json
generated
62
package-lock.json
generated
|
@ -1886,6 +1886,11 @@
|
||||||
"integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==",
|
"integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"add-px-to-style": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/add-px-to-style/-/add-px-to-style-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-0ME1RB+oAUqBN5BFMQlvZ/KPJjo="
|
||||||
|
},
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "6.10.0",
|
"version": "6.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
|
||||||
|
@ -3712,6 +3717,16 @@
|
||||||
"utila": "~0.4"
|
"utila": "~0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dom-css": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-css/-/dom-css-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-/bwtWgFdCj4YcuEUcrvQ57nmogI=",
|
||||||
|
"requires": {
|
||||||
|
"add-px-to-style": "1.0.0",
|
||||||
|
"prefix-style": "2.0.1",
|
||||||
|
"to-camel-case": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dom-helpers": {
|
"dom-helpers": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
|
||||||
|
@ -7593,8 +7608,7 @@
|
||||||
"performance-now": {
|
"performance-now": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"pify": {
|
"pify": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
|
@ -8257,6 +8271,11 @@
|
||||||
"integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==",
|
"integrity": "sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"prefix-style": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prefix-style/-/prefix-style-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-ZrupqHDP2jCKXcIOhekSCTLJWgY="
|
||||||
|
},
|
||||||
"prepend-http": {
|
"prepend-http": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
|
||||||
|
@ -8428,6 +8447,14 @@
|
||||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"raf": {
|
||||||
|
"version": "3.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
|
||||||
|
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
|
||||||
|
"requires": {
|
||||||
|
"performance-now": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"randombytes": {
|
"randombytes": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
|
@ -8484,6 +8511,16 @@
|
||||||
"scheduler": "^0.13.6"
|
"scheduler": "^0.13.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-custom-scrollbars": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-custom-scrollbars/-/react-custom-scrollbars-4.2.1.tgz",
|
||||||
|
"integrity": "sha1-gw/ZUCkn6X6KeMIIaBOJmyqLZts=",
|
||||||
|
"requires": {
|
||||||
|
"dom-css": "^2.0.0",
|
||||||
|
"prop-types": "^15.5.10",
|
||||||
|
"raf": "^3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
"version": "16.8.6",
|
"version": "16.8.6",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
|
||||||
|
@ -10060,12 +10097,25 @@
|
||||||
"integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
|
"integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"to-camel-case": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-camel-case/-/to-camel-case-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-GlYFSy+daWKYzmamCJcyK29CPkY=",
|
||||||
|
"requires": {
|
||||||
|
"to-space-case": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"to-fast-properties": {
|
"to-fast-properties": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||||
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
|
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"to-no-case": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo="
|
||||||
|
},
|
||||||
"to-object-path": {
|
"to-object-path": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||||
|
@ -10108,6 +10158,14 @@
|
||||||
"repeat-string": "^1.6.1"
|
"repeat-string": "^1.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"to-space-case": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=",
|
||||||
|
"requires": {
|
||||||
|
"to-no-case": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"toidentifier": {
|
"toidentifier": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
"keycode": "^2.2.0",
|
"keycode": "^2.2.0",
|
||||||
"mainloop.js": "^1.0.4",
|
"mainloop.js": "^1.0.4",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
|
"react-custom-scrollbars": "^4.2.1",
|
||||||
"react-dom": "^16.8.6",
|
"react-dom": "^16.8.6",
|
||||||
"react-router-dom": "^5.0.1",
|
"react-router-dom": "^5.0.1",
|
||||||
"react-toastify": "^5.3.2",
|
"react-toastify": "^5.3.2",
|
||||||
|
|
|
@ -2,17 +2,22 @@ import { Singleton } from '@eix-js/utils'
|
||||||
import { Observable, fromEvent, BehaviorSubject } from 'rxjs'
|
import { Observable, fromEvent, BehaviorSubject } from 'rxjs'
|
||||||
import { map } from 'rxjs/operators'
|
import { map } from 'rxjs/operators'
|
||||||
import { multiply } from '../../vector2/helpers/basic'
|
import { multiply } from '../../vector2/helpers/basic'
|
||||||
|
import { sidebarWidth } from '../components/Sidebar'
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
export class Screen {
|
export class Screen {
|
||||||
public width = new BehaviorSubject<number>(window.innerWidth)
|
private getWidth() {
|
||||||
|
return window.innerWidth - sidebarWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
public width = new BehaviorSubject<number>(this.getWidth())
|
||||||
public height = new BehaviorSubject<number>(window.innerHeight)
|
public height = new BehaviorSubject<number>(window.innerHeight)
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
const resize = fromEvent(window, 'resize')
|
const resize = fromEvent(window, 'resize')
|
||||||
|
|
||||||
resize
|
resize
|
||||||
.pipe(map(() => window.innerWidth))
|
.pipe(map(() => this.getWidth()))
|
||||||
.subscribe(val => this.width.next(val))
|
.subscribe(val => this.width.next(val))
|
||||||
resize
|
resize
|
||||||
.pipe(map(() => window.innerHeight))
|
.pipe(map(() => window.innerHeight))
|
||||||
|
|
|
@ -9,7 +9,7 @@ import Language from './Language'
|
||||||
/**
|
/**
|
||||||
* The width of the sidebar
|
* The width of the sidebar
|
||||||
*/
|
*/
|
||||||
const sidebarWidth = 240
|
export const sidebarWidth = 240
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The z-index of the sidebar.
|
* The z-index of the sidebar.
|
||||||
|
|
|
@ -54,7 +54,7 @@ const LogicGateModal = () => {
|
||||||
key={index}
|
key={index}
|
||||||
className="logic-gate-item"
|
className="logic-gate-item"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
addGate(renderer.simulation, name)
|
addGate(renderer, name)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon className="lgi-icon logic-gate-item-type">
|
<Icon className="lgi-icon logic-gate-item-type">
|
||||||
|
@ -70,7 +70,7 @@ const LogicGateModal = () => {
|
||||||
href={randomItem(template.info)}
|
href={randomItem(template.info)}
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
// e.preventDefault()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon className="lgi-icon">info</Icon>
|
<Icon className="lgi-icon">info</Icon>
|
||||||
|
|
11
src/modules/modals/helpers/modalIsOpen.ts
Normal file
11
src/modules/modals/helpers/modalIsOpen.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { InputStore } from '../../input/stores/InputStore'
|
||||||
|
import { open as logicGateModalIsOpen } from '../../logic-gates/components/LogicGateModal'
|
||||||
|
import { CreateSimulationStore } from '../../create-simulation/stores/CreateSimulationStore'
|
||||||
|
|
||||||
|
export const modalIsOpen = () => {
|
||||||
|
return (
|
||||||
|
InputStore.data.open.value ||
|
||||||
|
logicGateModalIsOpen.value ||
|
||||||
|
CreateSimulationStore.data.open.value
|
||||||
|
)
|
||||||
|
}
|
|
@ -2,12 +2,34 @@ import { templateStore } from '../../saving/stores/templateStore'
|
||||||
import { SimulationError } from '../../errors/classes/SimulationError'
|
import { SimulationError } from '../../errors/classes/SimulationError'
|
||||||
import { Simulation } from '../classes/Simulation'
|
import { Simulation } from '../classes/Simulation'
|
||||||
import { Gate } from '../classes/Gate'
|
import { Gate } from '../classes/Gate'
|
||||||
|
import { add, relativeTo, multiply } from '../../vector2/helpers/basic'
|
||||||
|
import { SimulationRenderer } from '../../simulationRenderer/classes/SimulationRenderer'
|
||||||
|
import { DefaultGateTemplate } from '../constants'
|
||||||
|
import { vector2 } from '../../../common/math/classes/Transform'
|
||||||
|
|
||||||
export const addGate = (simulation: Simulation, templateName: string) => {
|
export const addGate = (renderer: SimulationRenderer, templateName: string) => {
|
||||||
const template = templateStore.get(templateName)
|
const template = templateStore.get(templateName)
|
||||||
|
|
||||||
if (!template)
|
if (!template)
|
||||||
throw new SimulationError(`Cannot find template ${templateName}`)
|
throw new SimulationError(`Cannot find template ${templateName}`)
|
||||||
|
|
||||||
simulation.push(new Gate(template))
|
const gate = new Gate(template)
|
||||||
|
|
||||||
|
const gateScale =
|
||||||
|
template.shape && template.shape.scale
|
||||||
|
? (template.shape.scale as vector2)
|
||||||
|
: DefaultGateTemplate.shape.scale
|
||||||
|
|
||||||
|
const origin = relativeTo(
|
||||||
|
multiply(gateScale, 0.5),
|
||||||
|
relativeTo(renderer.camera.transform.position, renderer.screen.center)
|
||||||
|
)
|
||||||
|
|
||||||
|
const scalarOffset = renderer.options.spawning.spawnOffset
|
||||||
|
const offset = multiply([scalarOffset, scalarOffset], renderer.spawnCount)
|
||||||
|
|
||||||
|
gate.transform.position = add(origin, offset)
|
||||||
|
|
||||||
|
renderer.simulation.push(gate)
|
||||||
|
renderer.spawnCount++
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ import merge from 'deepmerge'
|
||||||
import { wireConnectedToGate } from '../helpers/wireConnectedToGate'
|
import { wireConnectedToGate } from '../helpers/wireConnectedToGate'
|
||||||
import { updateMouse, handleScroll } from '../helpers/scaleCanvas'
|
import { updateMouse, handleScroll } from '../helpers/scaleCanvas'
|
||||||
import { RefObject } from 'react'
|
import { RefObject } from 'react'
|
||||||
import { Singleton } from '@eix-js/utils'
|
|
||||||
import { dumpSimulation } from '../../saving/helpers/dumpSimulation'
|
import { dumpSimulation } from '../../saving/helpers/dumpSimulation'
|
||||||
|
import { modalIsOpen } from '../../modals/helpers/modalIsOpen'
|
||||||
|
|
||||||
export class SimulationRenderer {
|
export class SimulationRenderer {
|
||||||
public mouseDownOutput = new Subject<MouseEventInfo>()
|
public mouseDownOutput = new Subject<MouseEventInfo>()
|
||||||
|
@ -48,6 +48,9 @@ export class SimulationRenderer {
|
||||||
private mouseState = 0b00
|
private mouseState = 0b00
|
||||||
private gateSelectionOffset: vector2 = [0, 0]
|
private gateSelectionOffset: vector2 = [0, 0]
|
||||||
|
|
||||||
|
// this is used for spawning gates
|
||||||
|
public spawnCount = 0
|
||||||
|
|
||||||
public selectedPins: SelectedPins = {
|
public selectedPins: SelectedPins = {
|
||||||
start: null,
|
start: null,
|
||||||
end: null
|
end: null
|
||||||
|
@ -204,6 +207,8 @@ export class SimulationRenderer {
|
||||||
this.camera.transform.position,
|
this.camera.transform.position,
|
||||||
invert(offset)
|
invert(offset)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
this.spawnCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastMousePosition = this.camera.toWordPostition(event.position)
|
this.lastMousePosition = this.camera.toWordPostition(event.position)
|
||||||
|
@ -218,9 +223,11 @@ export class SimulationRenderer {
|
||||||
public updateWheelListener() {
|
public updateWheelListener() {
|
||||||
if (this.ref.current) {
|
if (this.ref.current) {
|
||||||
this.ref.current.addEventListener('wheel', event => {
|
this.ref.current.addEventListener('wheel', event => {
|
||||||
|
if (!modalIsOpen()) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
handleScroll(event, this.camera)
|
handleScroll(event, this.camera)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@ export const defaultSimulationRendererOptions: SimulationRendererOptions = {
|
||||||
wires: {
|
wires: {
|
||||||
temporaryWireColor: `rgba(128,128,128,0.5)`,
|
temporaryWireColor: `rgba(128,128,128,0.5)`,
|
||||||
curvePointOffset: 100
|
curvePointOffset: 100
|
||||||
|
},
|
||||||
|
spawning: {
|
||||||
|
spawnOffset: 30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,4 +21,7 @@ export interface SimulationRendererOptions {
|
||||||
temporaryWireColor: string
|
temporaryWireColor: string
|
||||||
curvePointOffset: number
|
curvePointOffset: number
|
||||||
}
|
}
|
||||||
|
spawning: {
|
||||||
|
spawnOffset: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue