2022-12-01 12:03:34 +01:00
|
|
|
<template>
|
|
|
|
<main id="mainContent">
|
|
|
|
<canvas
|
|
|
|
id="canvas-board"
|
|
|
|
ref="canvas-board"
|
|
|
|
:width="canvasWidth"
|
|
|
|
:height="canvasHeight"
|
2022-12-01 20:37:03 +01:00
|
|
|
/>
|
2022-12-01 12:03:34 +01:00
|
|
|
</main>
|
|
|
|
</template>
|
|
|
|
<script>
|
2022-12-02 17:11:34 +01:00
|
|
|
import { mapActions, mapState, mapWritableState } from "pinia";
|
2022-12-02 17:10:21 +01:00
|
|
|
import { globalStore } from "../stores/index.js";
|
|
|
|
import {
|
|
|
|
create1dState,
|
|
|
|
create1dStateOneCell,
|
|
|
|
create2dState,
|
|
|
|
createBoard,
|
|
|
|
conwayRules,
|
|
|
|
evolve2d,
|
|
|
|
} from "../modules/automata.js";
|
|
|
|
import { getRandomInt, sleep } from "../modules/common.js";
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: "CanvasBoard",
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
canvas: null,
|
|
|
|
ctx: null,
|
|
|
|
};
|
2022-12-01 23:58:04 +01:00
|
|
|
},
|
2022-12-02 17:10:21 +01:00
|
|
|
computed: {
|
|
|
|
...mapState(globalStore, {
|
|
|
|
cellProperties: "cellProperties",
|
|
|
|
rules: "rules1d",
|
|
|
|
refreshRate: "refreshRate",
|
|
|
|
initial1dState: "initial1dState",
|
|
|
|
drawingDirection: "drawingDirection",
|
|
|
|
canDraw: "canDraw",
|
|
|
|
getDraw1d: "draw1d",
|
|
|
|
getDraw2d: "draw2d",
|
|
|
|
getDraw2dLast: "draw2dLast",
|
|
|
|
}),
|
|
|
|
...mapWritableState(globalStore, {
|
|
|
|
lastBoard: "lastBoard",
|
|
|
|
canvasWidth: "canvasWidth",
|
|
|
|
canvasHeight: "canvasHeight",
|
|
|
|
getReset: "reset",
|
|
|
|
}),
|
|
|
|
boardWidth: function () {
|
|
|
|
return Math.floor(this.canvasWidth / this.cellProperties.size);
|
|
|
|
},
|
|
|
|
boardHeight: function () {
|
|
|
|
return Math.floor(this.canvasHeight / this.cellProperties.size);
|
|
|
|
},
|
2022-12-01 23:58:04 +01:00
|
|
|
},
|
2022-12-02 17:10:21 +01:00
|
|
|
watch: {
|
|
|
|
getDraw1d(value) {
|
|
|
|
if (value == true) this.draw1d();
|
|
|
|
},
|
|
|
|
getDraw2d(value) {
|
|
|
|
if (value == true) this.draw2dNew();
|
|
|
|
},
|
|
|
|
getDraw2dLast(value) {
|
|
|
|
if (value == true) this.draw2dLast();
|
|
|
|
},
|
|
|
|
getReset(value) {
|
|
|
|
if (value == true) this.reset();
|
|
|
|
},
|
2022-12-01 23:58:04 +01:00
|
|
|
},
|
2022-12-02 17:10:21 +01:00
|
|
|
mounted() {
|
|
|
|
this.canvas = Object.freeze(document.getElementById("canvas-board"));
|
|
|
|
this.ctx = this.canvas.getContext("2d");
|
2022-12-02 17:11:34 +01:00
|
|
|
this.canvasWidth = this.canvas.parentElement.clientWidth;
|
|
|
|
this.canvasHeight = this.canvas.parentElement.clientHeight;
|
2022-12-01 20:37:03 +01:00
|
|
|
},
|
2022-12-02 17:10:21 +01:00
|
|
|
methods: {
|
|
|
|
...mapActions(globalStore, ["toggleStop"]),
|
|
|
|
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;
|
|
|
|
})();
|
|
|
|
if (this.drawingDirection === "x")
|
|
|
|
this.ctx.fillRect(y * d, x * d, d, d);
|
|
|
|
else this.ctx.fillRect(x * d, y * d, d, d);
|
|
|
|
return cell;
|
|
|
|
});
|
2022-12-01 20:37:03 +01:00
|
|
|
});
|
2022-12-02 17:10:21 +01:00
|
|
|
},
|
|
|
|
compute1dInitialState() {
|
|
|
|
if (this.initial1dState === "onecell")
|
|
|
|
return create1dStateOneCell(this.boardWidth);
|
|
|
|
return create1dState(this.boardWidth, getRandomInt, [0, 2]);
|
|
|
|
},
|
|
|
|
draw1d() {
|
|
|
|
const initialState = this.compute1dInitialState();
|
|
|
|
const board = createBoard(
|
|
|
|
initialState,
|
|
|
|
this.rules.rules,
|
|
|
|
this.boardWidth
|
|
|
|
);
|
2022-12-02 17:11:34 +01:00
|
|
|
this.lastBoard = Object.freeze(board);
|
2022-12-02 17:10:21 +01:00
|
|
|
this.drawCanvas(board);
|
2022-12-02 17:11:34 +01:00
|
|
|
this.toggleStop();
|
2022-12-02 17:10:21 +01:00
|
|
|
},
|
|
|
|
draw2d(board) {
|
2022-12-01 23:58:04 +01:00
|
|
|
if (!this.canDraw) return;
|
2022-12-02 17:10:21 +01:00
|
|
|
const draw2dNext = async (b) => {
|
|
|
|
if (!this.canDraw) return;
|
|
|
|
const newBoard = evolve2d(b, conwayRules);
|
|
|
|
this.drawCanvas(b, this.cellProperties);
|
|
|
|
await sleep(this.refreshRate);
|
|
|
|
draw2dNext(newBoard);
|
|
|
|
};
|
|
|
|
return draw2dNext(board);
|
|
|
|
},
|
|
|
|
draw2dNew() {
|
|
|
|
const initialState = create2dState(
|
|
|
|
this.boardWidth,
|
|
|
|
this.boardHeight,
|
|
|
|
getRandomInt,
|
|
|
|
[0, 2]
|
|
|
|
);
|
|
|
|
const board = evolve2d(initialState, conwayRules);
|
2022-12-02 17:11:34 +01:00
|
|
|
this.lastBoard = Object.freeze(board);
|
2022-12-02 17:10:21 +01:00
|
|
|
this.draw2d(board);
|
|
|
|
},
|
|
|
|
async draw2dLast() {
|
2022-12-02 17:11:34 +01:00
|
|
|
if (this.lastBoard != undefined) this.draw2d(this.lastBoard);
|
2022-12-02 17:10:21 +01:00
|
|
|
},
|
|
|
|
reset() {
|
2022-12-02 17:11:34 +01:00
|
|
|
this.toggleStop();
|
2022-12-02 17:10:21 +01:00
|
|
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
2022-12-02 17:11:34 +01:00
|
|
|
this.getReset = 0;
|
2022-12-02 17:10:21 +01:00
|
|
|
},
|
2022-12-01 12:03:34 +01:00
|
|
|
},
|
2022-12-02 17:10:21 +01:00
|
|
|
};
|
2022-12-01 12:03:34 +01:00
|
|
|
</script>
|
|
|
|
<style>
|
2022-12-02 17:10:21 +01:00
|
|
|
#mainContent {
|
|
|
|
min-width: 70%;
|
|
|
|
}
|
2022-12-01 12:03:34 +01:00
|
|
|
</style>
|