🆖 added silentRefresh and fixed the glitchy wire bug exploit thing 🏉

This commit is contained in:
Matei Adriel 2019-06-04 18:38:01 +00:00
parent 1db7a58aee
commit e7abdd3c05
5 changed files with 236 additions and 70 deletions

View file

@ -2,14 +2,142 @@
<html lang="en"> <html lang="en">
<head> <head>
<title>Game</title> <title>Game</title>
<style>
html,
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
body {
background: #222;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.sk-folding-cube {
margin: 20px auto;
width: 40px;
height: 40px;
position: relative;
-webkit-transform: rotateZ(45deg);
transform: rotateZ(45deg);
}
.sk-folding-cube .sk-cube {
float: left;
width: 50%;
height: 50%;
position: relative;
-webkit-transform: scale(1.1);
-ms-transform: scale(1.1);
transform: scale(1.1);
}
.sk-folding-cube .sk-cube:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #bbb;
-webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
animation: sk-foldCubeAngle 2.4s infinite linear both;
-webkit-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
transform-origin: 100% 100%;
}
.sk-folding-cube .sk-cube2 {
-webkit-transform: scale(1.1) rotateZ(90deg);
transform: scale(1.1) rotateZ(90deg);
}
.sk-folding-cube .sk-cube3 {
-webkit-transform: scale(1.1) rotateZ(180deg);
transform: scale(1.1) rotateZ(180deg);
}
.sk-folding-cube .sk-cube4 {
-webkit-transform: scale(1.1) rotateZ(270deg);
transform: scale(1.1) rotateZ(270deg);
}
.sk-folding-cube .sk-cube2:before {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
.sk-folding-cube .sk-cube3:before {
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
}
.sk-folding-cube .sk-cube4:before {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}
@-webkit-keyframes sk-foldCubeAngle {
0%,
10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0;
}
25%,
75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1;
}
90%,
100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0;
}
}
@keyframes sk-foldCubeAngle {
0%,
10% {
-webkit-transform: perspective(140px) rotateX(-180deg);
transform: perspective(140px) rotateX(-180deg);
opacity: 0;
}
25%,
75% {
-webkit-transform: perspective(140px) rotateX(0deg);
transform: perspective(140px) rotateX(0deg);
opacity: 1;
}
90%,
100% {
-webkit-transform: perspective(140px) rotateY(180deg);
transform: perspective(140px) rotateY(180deg);
opacity: 0;
}
}
</style>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel='stylesheet' href='style.css'> <link rel='stylesheet' href='style.css'>
</head> </head>
<body ondragstart="return false;" ondrop="return false;" oncontextmenu="return false"> <body ondragstart="return false;" ondrop="return false;" oncontextmenu="return false">
loading <div class="sk-folding-cube">
<div class="sk-cube1 sk-cube"></div>
<div class="sk-cube2 sk-cube"></div>
<div class="sk-cube4 sk-cube"></div>
<div class="sk-cube3 sk-cube"></div>
</div>
</body> </body>
</html> </html>

View file

@ -24,6 +24,7 @@ export class Component {
public id: number public id: number
public material: Material public material: Material
public clickedChanges = new BehaviorSubject(false) public clickedChanges = new BehaviorSubject(false)
public scaling = false
private mouserDelta: number[] private mouserDelta: number[]
private strokeColor = "#888888" private strokeColor = "#888888"
@ -35,6 +36,22 @@ export class Component {
public inputPins: Pin[] = [] public inputPins: Pin[] = []
public outputPins: 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, constructor(private template: string,
position: [number, number] = [0, 0], position: [number, number] = [0, 0],
scale: [number, number] = [0, 0], scale: [number, number] = [0, 0],
@ -87,6 +104,7 @@ export class Component {
public handleMouseUp() { public handleMouseUp() {
this.clicked = false this.clicked = false
this.scaling = false
this.clickedChanges.next(this.clicked) this.clickedChanges.next(this.clicked)
} }
@ -110,8 +128,6 @@ export class Component {
} }
handleClick(e: MouseEvent) { handleClick(e: MouseEvent) {
console.log(e.button)
if (e.button === 0) { if (e.button === 0) {
const mousePosition = Component.screen.getWorldPosition(e.clientX, e.clientY) const mousePosition = Component.screen.getWorldPosition(e.clientX, e.clientY)
@ -125,6 +141,9 @@ export class Component {
this.activate(0) this.activate(0)
} }
else if (e.button === 1) {
this.scaling = true
}
else if (e.button === 2) { else if (e.button === 2) {
manager.components = manager.components.filter(({ id }) => id !== this.id) manager.components = manager.components.filter(({ id }) => id !== this.id)
manager.wireManager.wires manager.wireManager.wires
@ -132,9 +151,7 @@ export class Component {
.forEach(val => { .forEach(val => {
manager.wireManager.remove(val) manager.wireManager.remove(val)
}) })
manager.wireManager.update.next(true) manager.silentRefresh()
manager.update()
} }
} }
@ -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") { pinsSvg(pinScale: number, pinLength = 20, mode = "input") {
const stroke = 3 const stroke = 3
@ -208,8 +203,8 @@ export class Component {
} }
public pinx(mode = true, pinLength = 15) { public pinx(mode = true, pinLength = 15) {
return this.x.pipe( return this.position.pipe(
map(val => val + ( map(val => val[0] + (
(mode) ? (mode) ?
-pinLength : -pinLength :
this.scale.value[0] + pinLength this.scale.value[0] + pinLength

View file

@ -27,9 +27,9 @@ export class ComponentManager {
public placeholder = new BehaviorSubject("Create simulation") public placeholder = new BehaviorSubject("Create simulation")
public barAlpha = new BehaviorSubject<string>("0"); public barAlpha = new BehaviorSubject<string>("0");
public wireManager = new WireManager() public wireManager = new WireManager()
public onTop: Component
private temporaryCommnad = "" private temporaryCommnad = ""
private onTop: Component
private clicked = false private clicked = false
private screen = new Screen() private screen = new Screen()
@ -51,6 +51,7 @@ export class ComponentManager {
private closeInputEvent = new KeyboardInput("enter") private closeInputEvent = new KeyboardInput("enter")
private ctrlEvent = new KeyboardInput("ctrl") private ctrlEvent = new KeyboardInput("ctrl")
private palleteEvent = new KeyboardInput("p") private palleteEvent = new KeyboardInput("p")
private undoEvent = new KeyboardInput("z")
private shiftEvent = new KeyboardInput("shift") private shiftEvent = new KeyboardInput("shift")
private refreshEvent = new KeyboardInput("r") private refreshEvent = new KeyboardInput("r")
private clearEvent = new KeyboardInput("delete") private clearEvent = new KeyboardInput("delete")
@ -105,9 +106,10 @@ export class ComponentManager {
clear: () => this.clear(), clear: () => this.clear(),
clean: () => this.smartClear(), clean: () => this.smartClear(),
save: () => this.save(), save: () => this.save(),
refresh: () => this.refresh(), undo: () => this.refresh(),
download: () => download(this, [], []), download: () => download(this, [], []),
delete: () => this.delete(this.name) delete: () => this.delete(this.name),
refresh: () => this.silentRefresh(true)
} }
constructor() { constructor() {
@ -172,9 +174,12 @@ export class ComponentManager {
else if (this.saveEvent.value) { else if (this.saveEvent.value) {
this.save() this.save()
} }
else if (this.refreshEvent.value) { else if (this.undoEvent.value) {
this.refresh() this.refresh()
} }
else if (this.refreshEvent.value){
this.silentRefresh(true)
}
} }
else if (this.clearEvent.value) { else if (this.clearEvent.value) {
if (this.shiftEvent.value) if (this.shiftEvent.value)
@ -328,7 +333,7 @@ All you work will be lost!`
success("Succesfully cleared all components", "", this.alertOptions) success("Succesfully cleared all components", "", this.alertOptions)
} }
refresh() { public refresh() {
if (this.store.get(this.name)) { if (this.store.get(this.name)) {
this.loadState(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) { if (toAddOnTop >= 0) {
this.onTop = this.components[toAddOnTop] this.top(this.components[toAddOnTop])
this.components.push(this.onTop)
this.update()
} }
else if (outsideComponents && this.clicked) { 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 let toRemoveDuplicatesFor: Component
const result = this.components.map(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) { public getComponentById(id: number) {
return this.components.find(val => val.id === id) return this.components.find(val => val.id === id)
} }
loadState(state: ManagerState) { private loadState(state: ManagerState) {
if (!state.wires) //old state if (!state.wires) //old state
return return

View file

@ -1,20 +1,21 @@
import { Subject, fromEvent, BehaviorSubject, combineLatest } from "rxjs" import { fromEvent, BehaviorSubject, combineLatest } from "rxjs"
import { Singleton } from "@eix/utils" import { Singleton } from "@eix/utils"
import { map } from "rxjs/operators"; import { map, take } from "rxjs/operators";
import clamp from "../clamp/clamp"; import clamp from "../clamp/clamp";
import { manager } from "../../main";
@Singleton @Singleton
export class Screen { export class Screen {
width = new BehaviorSubject<number>(0) width = new BehaviorSubject<number>(0)
height = new BehaviorSubject<number>(0) height = new BehaviorSubject<number>(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) this.getViewBox(...values)
)); ));
public position = [0, 0] public position = [0, 0]
public scale = [2, 2] public scale = [2, 2]
private zoomLimits: [number,number] = [0.1,10] private zoomLimits: [number, number] = [0.1, 10]
private scrollStep = 1.3 private scrollStep = 1.3
public mousePosition = [this.width.value / 2, this.height.value / 2] public mousePosition = [this.width.value / 2, this.height.value / 2]
@ -25,34 +26,51 @@ export class Screen {
fromEvent(window, "resize").subscribe(() => this.update()) fromEvent(window, "resize").subscribe(() => this.update())
} }
updateMouse(e:MouseEvent){ updateMouse(e: MouseEvent) {
this.mousePosition = [e.clientX,e.clientY] this.mousePosition = [e.clientX, e.clientY]
} }
handleScroll(e: WheelEvent){ handleScroll(e: WheelEvent) {
e.preventDefault() e.preventDefault()
const size = [this.width.value,this.height.value] const componentToScale = manager.scaling
const mouseFraction = size.map((value,index) => this.mousePosition[index] / value)
const sign = e.deltaY / Math.abs(e.deltaY) const sign = e.deltaY / Math.abs(e.deltaY)
const zoom = this.scrollStep ** sign 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 if (componentToScale) {
this.position = this.position.map((value,index) => value - delta[index]) const oldScale = componentToScale.scale.value
this.update() 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[0] += x * this.scale[0]
this.position[1] += y * this.scale[1] this.position[1] += y * this.scale[1]
this.update() this.update()
} }
getViewBox(width: number, height:number) { getViewBox(width: number, height: number) {
return [ return [
this.position[0], this.position[0],
this.position[1], this.position[1],
@ -66,7 +84,7 @@ export class Screen {
this.width.next(window.innerWidth) this.width.next(window.innerWidth)
} }
getWorldPosition(x:number, y:number) { getWorldPosition(x: number, y: number) {
return [x * this.scale[0], y * this.scale[1]] return [x * this.scale[0], y * this.scale[1]]
} }
} }

View file

@ -26,7 +26,7 @@ export class WireManager {
this.tryResolving() this.tryResolving()
} }
public dispose(){ public dispose() {
for (let i of this.wires) for (let i of this.wires)
i.dispose() i.dispose()
@ -57,24 +57,27 @@ export class WireManager {
} }
get svg() { get svg() {
return this.wires.map(val => { return svg`${this.wires.map((val) => {
const i = val.input.of const i = val.input.of
const o = val.output.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` return svg`
<line x1=${subscribe(i.pinx(false, 20))} <line x2=${subscribe(i.pinx(false, 20))}
x2=${subscribe(o.pinx(true, 20))} x1=${subscribe(o.pinx(true, 20))}
y1=${subscribe(i.piny(false,i.outputPins.indexOf(val.input)))} y2=${subscribe(input)}
y2=${subscribe(o.piny(true,o.inputPins.indexOf(val.output)))} y1=${subscribe(output)}
stroke=${subscribe(val.input.svgColor)} stroke=${subscribe(val.input.svgColor)}
stroke-width=10 stroke-width=10
@click=${() => this.remove(val)} @click=${() => this.remove(val)}
> >
</line> </line>
`}) `})}`
} }
get state() { get state() {
return this.wires.map((val):WireStateVal => ({ return this.wires.map((val): WireStateVal => ({
from: { from: {
owner: val.input.of.id, owner: val.input.of.id,
index: val.input.of.outputPins.indexOf(val.input) index: val.input.of.outputPins.indexOf(val.input)