[wip] vuex, submenu templates, linting rules

This commit is contained in:
Ali Gator 2022-01-09 11:47:18 +01:00
parent b2057d0244
commit 5fe9243560
15 changed files with 8679 additions and 3797 deletions

12
.eslintrc.js Normal file
View File

@ -0,0 +1,12 @@
module.exports = {
extends: [
// add more generic rulesets here, such as:
'eslint:recommended',
//'plugin:vue/vue3-recommended',
'plugin:vue/recommended', // Use this if you are using Vue.js 2.x.
],
rules: {
// override/add rules settings here, such as:
// 'vue/no-unused-vars': 'error'
}
}

11917
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,12 +8,16 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vue/cli": "^4.5.15",
"@vue/cli-service-global": "^4.5.15",
"core-js": "^3.6.5",
"vue": "^2.6.11"
"vue": "^2.6.11",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",

View File

@ -1,20 +1,26 @@
<template>
<div id="main">
<h1 id="main-title">Cellular Automata Explorer</h1>
<div id="container">
<MainMenu/>
<Canvas/>
</div>
<div id="main">
<h1
id="main-title"
>
Cellular Automata Explorer
</h1>
<div id="container">
<MainMenu />
<Canvas />
</div>
</div>
</template>
<script>
import MainMenu from './components/MainMenu.vue'
import Canvas from './components/Canvas.vue'
export default {
name: 'App',
components: {
MainMenu
MainMenu,
Canvas
}
}
</script>

View File

@ -1,5 +1,73 @@
<template>
<main id="main">
<canvas width="500" height="500" id="canvas"></canvas>
<canvas
id="canvas"
ref="canvas"
width="500"
height="500"
/>
</main>
</template>
<script>
import { initialState1d, createBoard } from '../modules/automata.js'
import { getRandomInt } from '../modules/common.js'
export default {
name: 'Canvas',
data() {
return {
canvas: null,
ctx: null
}
},
computed: {
cellProperties() {
return this.$store.state.cellProperties
},
rules() {
return this.$store.state.rules1d
}
},
mounted() {
this.canvas = this.$refs['canvas']
this.canvas.width = 1280
this.canvas.height = 720
this.context = this.canvas.getContext('2d')
this.$root.$on('draw1d', () => { this.draw1d() })
},
methods: {
drawCanvas(board) {
const props = this.CellProperties;
board.map((row, y) => {
const d = props.size;
return row.map(
(cell, x) => {
this.ctx.fillStyle = (
() => {
if (cell === 1) return props.liveColor;
return props.deadColor;
})();
this.ctx.fillRect(x * d, y * d, d, d);
return cell;
},
);
});
},
draw1d() {
const rules = this.rules;
const props = this.CellProperties;
console.log(props.size)
const initialState = initialState1d(
Math.floor(this.canvas.width / props.size),
getRandomInt,
[0, 2],
);
const board = createBoard(
initialState,
rules,
Math.floor(this.canvas.height / props.size));
this.drawCanvas(board);
}
}
}
</script>

View File

@ -1,100 +1,25 @@
<template>
<div id="sidebar">
<MenuRow row-title="General Properties">
<div class="form-field">
<label for="live">Canvas Resolution</label>
</div>
<div class="form-field">
<input name="canvasWidth" type="number" id="canvasWidth" value="1280"/>
</div>
<div class="form-field">
<input name="canvasHeight" type="number" id="canvasHeight" value="1024"/>
</div>
<div class="form-field">
<input type="button" name="canvasRefresh" id="canvasRefresh" value="refresh"/>
</div>
</MenuRow>
<MenuRow row-title="Cell Properties">
<div class="form-field">
<label for="live">Living cell color</label>
<input name="live" type="color" id="live" value="#000000"/>
</div>
<div class="form-field">
<label for="dead">Dead cell color</label>
<input name="dead" type="color" id="dead" value="#AA78E8"/>
</div>
<div class="form-field">
<label>Cell size</label>
<input name="cellSize" type="number" id="cellSize" value="5"/>
</div>
</MenuRow>
<MenuRow row-title="Elementary Cellular Automata">
<div class="form-field">
<label>Rules</label>
</div>
<div class="form-field">
<label>111
<input type="checkbox" name="111" checked>
</label>
</div>
<div class="form-field">
<label>110
<input type="checkbox" name="110">
</label>
</div>
<div class="form-field">
<label>101
<input type="checkbox" name="101" checked>
</label>
</div>
<div class="form-field">
<label>100
<input type="checkbox" name="100">
</label>
</div>
<div class="form-field">
<label>011
<input type="checkbox" name="011" checked>
</label>
</div>
<div class="form-field">
<label>010
<input type="checkbox" name="010">
</label>
</div>
<div class="form-field">
<label>001
<input type="checkbox" name="001">
</label>
</div>
<div class="form-field">
<label>000
<input type="checkbox" name="000" checked>
</label>
</div>
<div class="form-field">
<input type="button" name="start" id="start" value="start"/>
<input type="button" name="stop" class="stop" value="stop"/>
<input type="button" name="reset" class="reset" value="reset"/>
</div>
</MenuRow>
<MenuRow row-title="2D Cellular Automata">
<div class="form-field">
<input type="button" name="start2d" id="start2d" value="start"/>
<input type="button" name="stop" class="stop" value="stop"/>
<input type="button" name="reset" class="reset" value="reset"/>
</div>
</MenuRow>
</div>
<div id="sidebar">
<MenuGeneralOptions />
<MenuCellProperties />
<MenuElementaryCA />
<Menu2dCA />
</div>
</template>
<script>
import MenuRow from './MenuRow.vue'
import MenuCellProperties from './MenuCellProperties.vue'
import MenuGeneralOptions from './MenuGeneralOptions.vue'
import MenuElementaryCA from './MenuElementaryCA.vue'
import Menu2dCA from './Menu2dCA.vue'
export default {
name: 'MainMenu',
components: {
MenuRow
}
MenuCellProperties,
MenuGeneralOptions,
MenuElementaryCA,
Menu2dCA
},
}
</script>

View File

@ -0,0 +1,34 @@
<template>
<MenuRow row-title="2D Cellular Automata">
<div class="form-field">
<input
id="start2d"
type="button"
name="start2d"
value="start"
>
<input
type="button"
name="stop"
class="stop"
value="stop"
>
<input
type="button"
name="reset"
class="reset"
value="reset"
>
</div>
</MenuRow>
</template>
<script>
import MenuRow from './MenuRow.vue'
export default {
name: 'Menu2dCA',
components: {
MenuRow
}
}
</script>

View File

@ -0,0 +1,60 @@
<template>
<MenuRow row-title="Cell Properties">
<form>
<div class="form-field">
<label for="live">Living cell color</label>
<input
id="live"
name="live"
type="color"
:value="liveColor"
@click="updateCellProperties"
>
</div>
<div class="form-field">
<label for="dead">Dead cell color</label>
<input
id="dead"
name="dead"
type="color"
:value="deadColor"
@click="updateCellProperties"
>
</div>
<div class="form-field">
<label>Cell size</label>
<input
id="cellSize"
name="cellSize"
type="number"
:value="size"
@click="updateCellProperties"
>
</div>
</form>
</MenuRow>
</template>
<script>
import MenuRow from './MenuRow.vue'
export default {
name: 'MainMenu',
components: {
MenuRow
},
data() {
return {
size : this.$store.state.cellProperties['size'],
liveColor : this.$store.state.cellProperties['liveColor'],
deadColor : this.$store.state.cellProperties['deadColor'],
}
},
methods: {
updateCellProperties(event) {
const elem = event.target
const prop = {'name' : elem.name, 'value' : elem.value}
this.$store.commit('setCellProperties', prop)
}
},
}
</script>

View File

@ -0,0 +1,128 @@
<template>
<MenuRow row-title="Elementary Cellular Automata">
<div class="form-field">
<label>Rules</label>
</div>
<form>
<div class="form-field">
<label>111
<input
type="checkbox"
name="111"
checked
@change="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>110
<input
type="checkbox"
name="110"
@click="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>101
<input
type="checkbox"
name="101"
checked
@click="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>100
<input
type="checkbox"
name="100"
@click="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>011
<input
type="checkbox"
name="011"
checked
@click="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>010
<input
type="checkbox"
name="010"
@click="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>001
<input
type="checkbox"
name="001"
@click="update1dRules"
>
</label>
</div>
<div class="form-field">
<label>000
<input
type="checkbox"
name="000"
checked
@click="update1dRules"
>
</label>
</div>
</form>
<div class="form-field">
<input
type="button"
name="start"
value="start"
@click="draw1d"
>
<input
type="button"
name="stop"
class="stop"
value="stop"
>
<input
type="button"
name="reset"
class="reset"
value="reset"
>
</div>
</MenuRow>
</template>
<script>
import MenuRow from './MenuRow.vue'
export default {
name: 'MenuElementaryCA',
components: {
MenuRow
},
methods: {
update1dRules(event) {
const elem = event.target
const value = elem.value == 'on' ? '1' : '0'
const data = { 'rule' : elem.name, 'value' : value}
this.$store.commit('update1dRules', data)
},
draw1d() {
this.$root.$emit('draw1d')
},
mounted() {
}
}
}
</script>

View File

@ -0,0 +1,43 @@
<template>
<MenuRow row-title="General Options">
<form>
<div class="form-field">
<label for="live">Canvas Resolution</label>
</div>
<div class="form-field">
<input
id="canvasWidth"
name="canvasWidth"
type="number"
value="1280"
>
</div>
<div class="form-field">
<input
id="canvasHeight"
name="canvasHeight"
type="number"
value="1024"
>
</div>
<div class="form-field">
<input
id="canvasRefresh"
type="button"
name="canvasRefresh"
value="refresh"
>
</div>
</form>
</MenuRow>
</template>
<script>
import MenuRow from './MenuRow.vue'
export default {
name: 'MenuGeneralOptions',
components: {
MenuRow
}
}
</script>

View File

@ -1,21 +1,27 @@
<template>
<div class="menu-row">
<h2
@click="isHidden = !isHidden"
> {{ RowTitle }}</h2>
<div class="menu-row-content" v-if="!isHidden">
<form>
<slot></slot>
</form>
<div class="menu-row">
<h2
@click="isHidden = !isHidden"
>
{{ rowTitle }}
</h2>
<div
v-if="!isHidden"
class="menu-row-content"
>
<slot />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'MenuRow',
props: {
RowTitle: String
rowTitle: {
type: String,
default : ''
}
},
data() {
return {

View File

@ -1,8 +1,10 @@
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store,
render: h => h(App)
}).$mount('#app')

View File

@ -144,23 +144,3 @@ canvasRefreshBtn.addEventListener('click', () => {
canvas.width = width;
canvas.height = height;
});
menuRow.forEach((elem) => {
elem.querySelector('h2').addEventListener('click', async (e) => {
const parent = e.currentTarget.parentNode;
const menuDisplay = parent.querySelector('.menu-row-content').style;
if (menuDisplay.display !== 'none') menuDisplay.setProperty('display', 'none');
else menuDisplay.setProperty('display', 'block');
});
});
window.addEventListener('load', () => {
resizeCanvas();
menuRowContent.forEach((elem) => {
elem.style.setProperty('display', 'none');
});
});
window.addEventListener('resize', () => {
// resizeCanvas();
});

27
src/store/index.js Normal file
View File

@ -0,0 +1,27 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
rules1d : {},
cellProperties: {
size: 5,
liveColor: '#000000',
deadColor: '#AA78E8',
},
},
mutations: {
update1dRules(state, data) {
state.rules1d[data.rule] = data.value
},
setCellProperties(state, data) {
state.cellProperties[data.name] = data.value
},
},
actions: {
},
modules: {
}
})

View File

@ -1,6 +1,10 @@
module.exports = {
configureWebpack: {
devServer: {
overlay: {
warnings: true,
errors: true
},
watchOptions: {
ignored: [/node_modules/, /public/, /\.#/],
}