From e7abdd3c058cbe3c82f6c212e7d2310958550b9d Mon Sep 17 00:00:00 2001 From: Matei Adriel Date: Tue, 4 Jun 2019 18:38:01 +0000 Subject: [PATCH] =?UTF-8?q?=20=F0=9F=86=96=20=20added=20silentRefresh=20an?= =?UTF-8?q?d=20fixed=20the=20glitchy=20wire=20bug=20exploit=20thing=20?= =?UTF-8?q?=F0=9F=8F=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.html | 134 +++++++++++++++++- src/ts/common/component/component.ts | 53 ++++--- .../componentManager/componentManager.ts | 42 ++++-- src/ts/common/screen.ts/screen.ts | 58 +++++--- src/ts/common/wires/wireManager.ts | 19 +-- 5 files changed, 236 insertions(+), 70 deletions(-) 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)