diff --git a/src/index.html b/src/index.html
index aa7287a..ec45343 100644
--- a/src/index.html
+++ b/src/index.html
@@ -2,14 +2,142 @@
- Game
+ Game
+
-
+
- loading
+
\ No newline at end of file
diff --git a/src/ts/common/component/component.ts b/src/ts/common/component/component.ts
index b807940..abe80c0 100644
--- a/src/ts/common/component/component.ts
+++ b/src/ts/common/component/component.ts
@@ -24,6 +24,7 @@ export class Component {
public id: number
public material: Material
public clickedChanges = new BehaviorSubject(false)
+ public scaling = false
private mouserDelta: number[]
private strokeColor = "#888888"
@@ -35,6 +36,22 @@ export class Component {
public inputPins: Pin[] = []
public outputPins: Pin[] = []
+ public x = this.position.pipe(map(val =>
+ val[0]
+ ))
+
+ public y = this.position.pipe(map(val =>
+ val[1]
+ ))
+
+ public width = this.scale.pipe(map(val =>
+ val[0]
+ ))
+
+ public height = this.scale.pipe(map(val =>
+ val[1]
+ ))
+
constructor(private template: string,
position: [number, number] = [0, 0],
scale: [number, number] = [0, 0],
@@ -87,6 +104,7 @@ export class Component {
public handleMouseUp() {
this.clicked = false
+ this.scaling = false
this.clickedChanges.next(this.clicked)
}
@@ -110,8 +128,6 @@ export class Component {
}
handleClick(e: MouseEvent) {
- console.log(e.button)
-
if (e.button === 0) {
const mousePosition = Component.screen.getWorldPosition(e.clientX, e.clientY)
@@ -125,6 +141,9 @@ export class Component {
this.activate(0)
}
+ else if (e.button === 1) {
+ this.scaling = true
+ }
else if (e.button === 2) {
manager.components = manager.components.filter(({ id }) => id !== this.id)
manager.wireManager.wires
@@ -132,9 +151,7 @@ export class Component {
.forEach(val => {
manager.wireManager.remove(val)
})
- manager.wireManager.update.next(true)
-
- manager.update()
+ manager.silentRefresh()
}
}
@@ -151,28 +168,6 @@ export class Component {
}
}
- get x() {
- return this.position.pipe(map(val =>
- val[0]
- ))
- }
- get y() {
- return this.position.pipe(map(val =>
- val[1]
- ))
- }
-
- get width() {
- return this.scale.pipe(map(val =>
- val[0]
- ))
- }
- get height() {
- return this.scale.pipe(map(val =>
- val[1]
- ))
- }
-
pinsSvg(pinScale: number, pinLength = 20, mode = "input") {
const stroke = 3
@@ -208,8 +203,8 @@ export class Component {
}
public pinx(mode = true, pinLength = 15) {
- return this.x.pipe(
- map(val => val + (
+ return this.position.pipe(
+ map(val => val[0] + (
(mode) ?
-pinLength :
this.scale.value[0] + pinLength
diff --git a/src/ts/common/componentManager/componentManager.ts b/src/ts/common/componentManager/componentManager.ts
index 4e4579c..1dbbaaa 100644
--- a/src/ts/common/componentManager/componentManager.ts
+++ b/src/ts/common/componentManager/componentManager.ts
@@ -27,9 +27,9 @@ export class ComponentManager {
public placeholder = new BehaviorSubject("Create simulation")
public barAlpha = new BehaviorSubject("0");
public wireManager = new WireManager()
+ public onTop: Component
private temporaryCommnad = ""
- private onTop: Component
private clicked = false
private screen = new Screen()
@@ -51,6 +51,7 @@ export class ComponentManager {
private closeInputEvent = new KeyboardInput("enter")
private ctrlEvent = new KeyboardInput("ctrl")
private palleteEvent = new KeyboardInput("p")
+ private undoEvent = new KeyboardInput("z")
private shiftEvent = new KeyboardInput("shift")
private refreshEvent = new KeyboardInput("r")
private clearEvent = new KeyboardInput("delete")
@@ -105,9 +106,10 @@ export class ComponentManager {
clear: () => this.clear(),
clean: () => this.smartClear(),
save: () => this.save(),
- refresh: () => this.refresh(),
+ undo: () => this.refresh(),
download: () => download(this, [], []),
- delete: () => this.delete(this.name)
+ delete: () => this.delete(this.name),
+ refresh: () => this.silentRefresh(true)
}
constructor() {
@@ -172,9 +174,12 @@ export class ComponentManager {
else if (this.saveEvent.value) {
this.save()
}
- else if (this.refreshEvent.value) {
+ else if (this.undoEvent.value) {
this.refresh()
}
+ else if (this.refreshEvent.value){
+ this.silentRefresh(true)
+ }
}
else if (this.clearEvent.value) {
if (this.shiftEvent.value)
@@ -328,7 +333,7 @@ All you work will be lost!`
success("Succesfully cleared all components", "", this.alertOptions)
}
- refresh() {
+ public refresh() {
if (this.store.get(this.name)) {
this.loadState(this.store.get(this.name))
}
@@ -369,10 +374,9 @@ All you work will be lost!`
}
}
+ // if (false) { }
if (toAddOnTop >= 0) {
- this.onTop = this.components[toAddOnTop]
- this.components.push(this.onTop)
- this.update()
+ this.top(this.components[toAddOnTop])
}
else if (outsideComponents && this.clicked) {
@@ -385,7 +389,21 @@ All you work will be lost!`
}
}
- render() {
+ public silentRefresh(verboose = false){
+ this.loadState(this.state)
+ if (verboose)
+ success("Succesfully reloaded all components", "", this.alertOptions)
+ }
+
+ public top(component: Component) {
+ if (this.onTop !== component) {
+ this.onTop = component
+ this.components.push(component)
+ }
+ this.update()
+ }
+
+ private render() {
let toRemoveDuplicatesFor: Component
const result = this.components.map(component => {
@@ -451,11 +469,15 @@ All you work will be lost!`
}
}
+ get scaling(): Component {
+ return this.components.find(val => val.scaling)
+ }
+
public getComponentById(id: number) {
return this.components.find(val => val.id === id)
}
- loadState(state: ManagerState) {
+ private loadState(state: ManagerState) {
if (!state.wires) //old state
return
diff --git a/src/ts/common/screen.ts/screen.ts b/src/ts/common/screen.ts/screen.ts
index 775ad34..e43ea4b 100644
--- a/src/ts/common/screen.ts/screen.ts
+++ b/src/ts/common/screen.ts/screen.ts
@@ -1,20 +1,21 @@
-import { Subject, fromEvent, BehaviorSubject, combineLatest } from "rxjs"
+import { fromEvent, BehaviorSubject, combineLatest } from "rxjs"
import { Singleton } from "@eix/utils"
-import { map } from "rxjs/operators";
+import { map, take } from "rxjs/operators";
import clamp from "../clamp/clamp";
+import { manager } from "../../main";
@Singleton
export class Screen {
width = new BehaviorSubject(0)
height = new BehaviorSubject(0)
- viewBox = combineLatest(this.width, this.height).pipe(map((values: [number,number]) =>
+ viewBox = combineLatest(this.width, this.height).pipe(map((values: [number, number]) =>
this.getViewBox(...values)
));
-
+
public position = [0, 0]
public scale = [2, 2]
- private zoomLimits: [number,number] = [0.1,10]
+ private zoomLimits: [number, number] = [0.1, 10]
private scrollStep = 1.3
public mousePosition = [this.width.value / 2, this.height.value / 2]
@@ -25,34 +26,51 @@ export class Screen {
fromEvent(window, "resize").subscribe(() => this.update())
}
- updateMouse(e:MouseEvent){
- this.mousePosition = [e.clientX,e.clientY]
+ updateMouse(e: MouseEvent) {
+ this.mousePosition = [e.clientX, e.clientY]
}
- handleScroll(e: WheelEvent){
+ handleScroll(e: WheelEvent) {
e.preventDefault()
- const size = [this.width.value,this.height.value]
- const mouseFraction = size.map((value,index) => this.mousePosition[index] / value)
+ const componentToScale = manager.scaling
const sign = e.deltaY / Math.abs(e.deltaY)
const zoom = this.scrollStep ** sign
- const newScale = this.scale.map(value => clamp(value * zoom, ...this.zoomLimits ))
- const delta = this.scale.map((value,index) =>
- size[index] * (newScale[index] - this.scale[index]) * mouseFraction[index]
- )
- this.scale = newScale
- this.position = this.position.map((value,index) => value - delta[index])
- this.update()
+ if (componentToScale) {
+ const oldScale = componentToScale.scale.value
+ const newScale = oldScale.map(val => val / zoom)
+
+ componentToScale.scale.next(newScale)
+ componentToScale.position.pipe(take(1)).subscribe(data => {
+ componentToScale.position.next(data.map((val, index) =>
+ val - (newScale[index] - oldScale[index]) / 2
+ ))
+ })
+
+ manager.top(componentToScale)
+ }
+ else {
+ const size = [this.width.value, this.height.value]
+ const mouseFraction = size.map((value, index) => this.mousePosition[index] / value)
+ const newScale = this.scale.map(value => clamp(value * zoom, ...this.zoomLimits))
+ const delta = this.scale.map((_, index) =>
+ size[index] * (newScale[index] - this.scale[index]) * mouseFraction[index]
+ )
+
+ this.scale = newScale
+ this.position = this.position.map((value, index) => value - delta[index])
+ this.update()
+ }
}
- move(x:number, y:number) {
+ move(x: number, y: number) {
this.position[0] += x * this.scale[0]
this.position[1] += y * this.scale[1]
this.update()
}
- getViewBox(width: number, height:number) {
+ getViewBox(width: number, height: number) {
return [
this.position[0],
this.position[1],
@@ -66,7 +84,7 @@ export class Screen {
this.width.next(window.innerWidth)
}
- getWorldPosition(x:number, y:number) {
+ getWorldPosition(x: number, y: number) {
return [x * this.scale[0], y * this.scale[1]]
}
}
\ No newline at end of file
diff --git a/src/ts/common/wires/wireManager.ts b/src/ts/common/wires/wireManager.ts
index dc8e7a6..dbb323e 100644
--- a/src/ts/common/wires/wireManager.ts
+++ b/src/ts/common/wires/wireManager.ts
@@ -26,7 +26,7 @@ export class WireManager {
this.tryResolving()
}
- public dispose(){
+ public dispose() {
for (let i of this.wires)
i.dispose()
@@ -57,24 +57,27 @@ export class WireManager {
}
get svg() {
- return this.wires.map(val => {
+ return svg`${this.wires.map((val) => {
const i = val.input.of
const o = val.output.of
+ const inputIndex = i.outputPins.indexOf(val.input)
+ const input = i.piny(false, inputIndex)
+ const output = o.piny(true, o.inputPins.indexOf(val.output))
return svg`
- this.remove(val)}
>
- `})
+ `})}`
}
get state() {
- return this.wires.map((val):WireStateVal => ({
+ return this.wires.map((val): WireStateVal => ({
from: {
owner: val.input.of.id,
index: val.input.of.outputPins.indexOf(val.input)