addes chinese and turkish

This commit is contained in:
Matei Adriel 2019-08-04 00:55:22 +03:00
parent 2e1a45fe19
commit 5f77e15b18
16 changed files with 266 additions and 54 deletions

View file

@ -23,7 +23,7 @@ Many thanks to:
- Multiple simulations support
- Integrated circuits
- Multiple bits per pin
- Multiple language support: Romanian, English, Dutch & more in the future
- Multiple language support: Romanian, English, Dutch, Turkish, Chinese & more in the future
## Playing with the source

View file

@ -1,2 +1,7 @@
/**
* Remoes al lduplicates from array
*
* @param array The array to remove duplicates from
*/
export const removeDuplicates = <T>(array: T[]): T[] =>
Array.from(new Set<T>(array).values())

View file

@ -1,3 +1,8 @@
/**
* Gets safe error stack from error
*
* @param error The error to get the safe erro stack from
*/
export const getSafeErrorStack = (error: any) => {
const errorString: string = error.toString()
const stackString: string = error.stack

View file

@ -1,10 +1,22 @@
import { allCombinations } from '../../../modules/simulation/helpers/allCombinations'
import { BehaviorSubject } from 'rxjs'
import { vector2 } from '../types/vector2'
import { vector4 } from '../types/vector4'
export class Transform {
/**
* Gets the position as a subject
*/
public positionSubject = new BehaviorSubject<vector2>([0, 0])
/**
* Class used to represend the position scale and rotation
* of a body in 2d space
*
* @param _position The initial position
* @param scale The initial scale
* @param rotation The initial scale of the object
*/
public constructor(
public _position: vector2 = [0, 0],
public scale: vector2 = [1, 1],
@ -13,12 +25,18 @@ export class Transform {
this.updatePositionSubject()
}
/**
* Gets the boundng box of the transform
*/
public getBoundingBox() {
const result = [...this.position, ...this.scale] as vector4
return result
}
/**
* Gets an array of all points in the transform
*/
public getPoints() {
const combinations = Array.from(allCombinations([0, 1], [0, 1]))
@ -31,17 +49,6 @@ export class Transform {
return points as vector2[]
}
public getEdges() {
const points = this.getPoints()
const edges = []
for (let index = 0; index < points.length; index++) {
edges.push([points[index], points[(index + 1) % points.length]])
}
return edges as [vector2, vector2][]
}
/**
* Pushes the current position trough the position subject
*/
@ -65,74 +72,106 @@ export class Transform {
this.updatePositionSubject()
}
/** Short forms for random stuff */
/**
* The first element of the position vector
*/
get x() {
return this.position[0]
}
/**
* The second element of the position vector
*/
get y() {
return this.position[1]
}
/**
* The first element of the scale vector
*/
get width() {
return this.scale[0]
}
/**
* The second element of the scale vector
*/
get height() {
return this.scale[1]
}
/**
* The minimum x position of the buonding box
*/
get minX() {
return Math.min(this.x, this.x + this.width)
}
/**
* The maximum x position of the bounding box
*/
get maxX() {
return Math.max(this.x, this.x + this.width)
}
/**
* The minimum y position of the buonding box
*/
get minY() {
return Math.min(this.y, this.y + this.height)
}
/**
* The maximum y position of the buonding box
*/
get maxY() {
return Math.max(this.y, this.y + this.height)
}
/**
* The center of the bounding box
*/
get center() {
return [this.x + this.width / 2, this.y + this.height / 2] as vector2
}
/**
* Sets the first element of the position vector
*
* @param value The value to set x to
*/
set x(value: number) {
this.position = [value, this.y]
this.updatePositionSubject()
}
/**
* Sets the second element of the position vector
*
* @param value The value to set y to
*/
set y(value: number) {
this.position = [this.x, value]
this.updatePositionSubject()
}
/**
* Sets the first element of the scale vector
*
* @param value The value to set the width to
*/
set width(value: number) {
this.scale = [value, this.height]
}
/**
* Sets the second element of the scale vector
*
* @param value The value to set the height to
*/
set height(value: number) {
this.scale = [this.width, value]
}
}
export type vector3 = [number, number, number]
export type vector4 = [number, number, number, number]
export type vector8 = [
number,
number,
number,
number,
number,
number,
number,
number
]

View file

@ -10,14 +10,20 @@
ondrop="return false;"
oncontextmenu="return false"
>
<!--The react app is rendered here-->
<div id="app"></div>
<!--The splash screen structure-->
<div class="Splash">
<!--Loading animation-->
<div class="loading">
<div class="lds-ripple">
<div></div>
<div></div>
</div>
</div>
<!--In case someone tries to laod this with js disabled-->
<noscript> JavaScript must be enabled to run this app. </noscript>
</div>
</body>

View file

@ -1,27 +1,40 @@
import { Splash } from './modules/splash/classes/Splash'
/**
* The function wich is run when the app is loaded
*/
async function main() {
// Create splash screen variable
let splash: Splash | undefined = undefined
try {
// instantiate splash screen
splash = new Splash()
} catch {}
try {
// import main app
const app = await import('./main')
// wait for app to start
await app.start()
} catch (error) {
// show the error to the client
if (splash) splash.setError(error)
// log the error to the console
console.error(error.stack || error)
return
}
// hide splash screen if it exists
if (splash) {
splash.fade()
}
}
// Call entry
main().catch(error => {
// if the error handling error has an error, log that error
console.error('Error loading app', error)
})

View file

@ -11,7 +11,11 @@ import { logWelcome } from './modules/core/helpers/logWelcome'
import { initRenderer } from './modules/simulationRenderer/helpers/initRenderer'
import { updateLogicGateList } from './modules/logic-gates/subjects/LogicGateList'
/**
* The function wich does the heavy lifting for starting the app
*/
export const start = async () => {
// This will resolve at the first render
const result = loadSubject
.pipe(
filter(a => a),
@ -19,14 +23,27 @@ export const start = async () => {
)
.toPromise()
// Handle possible errors
handleErrors()
// Create main renderer for the app
initRenderer()
// Register key bindings
initKeyBindings()
// Update base templates
initBaseTemplates()
// Easter egg
logWelcome()
// Update the logic gates in local storage
updateLogicGateList()
// Render app component
render(<App />, document.getElementById('app'))
// wait for the first render
await result
}

View file

@ -3,6 +3,8 @@ import { Translation } from './types/TranslationInterface'
import { EnglishTranslation } from './translations/english'
import { RomanianTranslation } from './translations/romanian'
import { DutchTranslation } from './translations/nederlands'
import { MandarinTranslation } from './translations/chinese'
import { TurkishTranslation } from './translations/turkish'
/**
* Object with all translations
@ -10,11 +12,15 @@ import { DutchTranslation } from './translations/nederlands'
export const translations: Record<supportedLanguage, Translation> = {
english: EnglishTranslation,
['română']: RomanianTranslation,
dutch: DutchTranslation
dutch: DutchTranslation,
['中文']: MandarinTranslation,
['türkçe']: TurkishTranslation
}
export const allSupportedLanguages: supportedLanguage[] = [
'english',
'română',
'dutch'
'dutch',
'中文',
'türkçe'
]

View file

@ -0,0 +1,53 @@
import { Translation } from '../types/TranslationInterface'
/**
* The enaglish translation
*/
export const MandarinTranslation: Translation = {
language: '中文',
sidebar: {
createSimulation: '创作',
logicGates: '逻辑门',
openSimulation: '打开模拟',
simulation: '模拟',
language: '语言',
backToSimulation: '回到模拟',
backToGates: '回到逻辑门'
},
createSimulation: {
mode: {
question: '你想要创造什么样的模拟?',
options: {
ic: '集成电路',
project: '项目'
}
},
name: {
question: '你希望你的模拟交什么?'
}
},
actions: {
save: '存盘',
clean: '清理',
refresh: '刷新',
undo: '消除',
paste: '粘贴',
copy: '重做',
duplicate: '复制',
cut: '剪切',
'select all': '全选',
'delete selection': '删去选着',
'delete simulation': '删去模拟'
},
messages: {
createdSimulation: name => `成功创建了模拟 '${name}'`,
switchedToSimulation: name => `成功切换到模拟 '${name}'`,
savedSimulation: name => `成功存盘了模拟 '${name}'`,
compiledIc: name => `成功编译了电路 '${name}'`,
cleaned: name => `成功清理了模拟 '${name}'`,
refreshed: name => `成功刷新了模拟 '${name}'`,
undone: name => `成功消除了模拟 '${name}'`,
deletedSimulation: name => `成功删去了模拟 '${name}'`,
addedGate: name => `成功加了逻辑门 '${name}'`
}
}

View file

@ -9,23 +9,23 @@ export const DutchTranslation: Translation = {
createSimulation: 'Maak simulatie',
logicGates: 'Logische poorten',
openSimulation: 'Open simulatie',
simulation: 'Todo',
simulation: 'Simulatie',
language: 'Taal',
backToSimulation: 'Todo',
backToGates: 'Todo'
backToSimulation: 'Terug naar simulatie',
backToGates: 'Terug naar poorten'
},
actions: {
'delete selection': 'Todo',
'select all': 'Todo',
clean: 'Todo',
refresh: 'Todo',
save: 'Todo',
undo: 'Todo',
'delete simulation': `Todo`,
copy: 'Todo',
cut: 'Todo',
duplicate: 'Todo',
paste: 'Todo'
'delete selection': 'Delete selectie',
'select all': 'Selecteer alles',
clean: 'Verwijder',
refresh: 'Ververs',
save: 'opslaan',
undo: 'ongedaan maken',
'delete simulation': 'Delete simulatie',
copy: 'Kopieer',
cut: 'Knippen',
duplicate: 'Dupliceer',
paste: 'Plak'
},
createSimulation: {
mode: {
@ -44,12 +44,12 @@ export const DutchTranslation: Translation = {
createdSimulation: name => `Simulatie '${name}' succesvol gecreerd`,
switchedToSimulation: name =>
`Succesvol veranderd naar simulatie '${name}'`,
savedSimulation: name => `Simulatie succesvol opgeslagen '${name}'`,
compiledIc: name => `IC gecompileerd: ${name}`,
cleaned: name => `${name} gewist`,
refreshed: name => `${name} ververst`,
undone: name => `${name} ongedaan gemaakt`,
deletedSimulation: name => `Todo`,
addedGate: name => 'Todo'
savedSimulation: name => "Simulatie succesvol opgeslagen '${name}'",
compiledIc: name => "IC gecompileerd: '${name}'",
cleaned: name => `'${name}' gewist`,
refreshed: name => `'${name}' ververst`,
undone: name => `'${name}' ongedaan gemaakt`,
deletedSimulation: name => `Simulatie '${name}' verwijderd`,
addedGate: name => `Poort '${name}' toegevoegd`
}
}

View file

@ -0,0 +1,53 @@
import { Translation } from '../types/TranslationInterface'
/**
* The enaglish translation
*/
export const TurkishTranslation: Translation = {
language: 'türkçe',
sidebar: {
createSimulation: 'defter yaziyor',
logicGates: 'kapilar',
openSimulation: 'defter açiyor',
simulation: 'defter',
language: 'dil',
backToSimulation: "defter'e geri dön",
backToGates: 'kapilara geri dön'
},
createSimulation: {
mode: {
question: 'bu defter türü ne?',
options: {
ic: 'defter gibi kapi',
project: 'Proje'
}
},
name: {
question: 'bu defter ad ne?'
}
},
actions: {
save: 'kayit',
clean: 'temizleyor',
refresh: 'feranlatiyor',
undo: 'geri almc',
paste: 'yapistirıyor',
copy: 'tuturuyor',
duplicate: 'klonuyor',
cut: 'kırpıyor',
'select all': 'seç her şey',
'delete selection': 'seçım siliyor',
'delete simulation': 'Defter siliyor'
},
messages: {
createdSimulation: name => `dizüstü çizdi '${name}'`,
switchedToSimulation: name => `ılan not defteri'${name}'`,
savedSimulation: name => `kaydedilmiş defter '${name}'`,
compiledIc: name => `derlenmiş kapı '${name}'`,
cleaned: name => `temizlenmiş defter '${name}'`,
refreshed: name => `yenilenmiş defter '${name}'`,
undone: name => `geri alındı '${name}'`,
deletedSimulation: name => `silinmiş defter '${name}'`,
addedGate: name => `eklenen kapı '${name}'`
}
}

View file

@ -1,4 +1,9 @@
/**
/**
* Type containing the names of all supported languages
*/
export type supportedLanguage = 'română' | 'english' | 'dutch'
export type supportedLanguage =
| 'română'
| 'english'
| 'dutch'
| '中文'
| 'türkçe'

View file

@ -18,7 +18,7 @@ const bitMergerTemplate: PartialTemplate = {
const a = context.get(0)
const b = context.get(1)
context.set(0, a + b)
context.set(0, b + a)
`
},
category: categories.compressing,

View file

@ -21,7 +21,7 @@ const bitSplitterTemplate: PartialTemplate = {
]
for (let index = 0; index < 2; index++ ) {
context.set(index, chunks[index])
context.set(index, chunks[1 - index])
}
`
},

View file

@ -1,5 +1,11 @@
import { Transform } from '../../../common/math/classes/Transform'
/**
* Checks collision between 2 rects
*
* @param rect1 The first rect
* @param rect2 The second rect
*/
export const aabbCollisionDetection = (rect1: Transform, rect2: Transform) => {
return !(
rect1.maxX < rect2.minX ||

View file

@ -1,12 +1,16 @@
import express, { static as _static } from 'express'
import { resolve } from 'path'
// create express app
const app = express()
// serve static assets
app.use(_static(__dirname))
// serve single page application
app.get('*', (rex, res) => {
res.sendFile(resolve(__dirname, 'index.html'))
})
// listen to the port from .env (default to 8080)
app.listen(process.env.PORT || 8080)