better brush preview in new component

This commit is contained in:
Hugh Bord 2021-08-06 11:51:58 +10:00
parent a1e27a8e22
commit cb5e558922
11 changed files with 484 additions and 133 deletions

View File

@ -138,7 +138,6 @@ export default {
},
name: "Dashboard",
data: () => ({
showNewAsciiModal: false,
currentTab: 1,
canvasX: null,
canvasY: null,
@ -176,7 +175,7 @@ export default {
return this.$store.getters.currentBg;
},
currentChar() {
return this.$store.getters.getChar;
return this.$store.getters.currentChar;
},
toolbarState() {
return this.$store.getters.toolbarState;

View File

@ -447,7 +447,7 @@ export const createNewAscii = (forms) => {
newAscii.blocks = LZString.compressToUTF16(JSON.stringify(newAscii.blocks));
newAscii.history.push(newAscii.blocks);
store.commit('newAsciibirdMeta', newAscii);
store.commit('openModal', 'new-ascii');
store.commit('closeModal', 'new-ascii');
return true;
};

View File

@ -0,0 +1,253 @@
<template>
<div>
</div>
</template>
<script>
import { emptyBlock, mircColours99 } from "../../ascii";
export default {
name: "BrushLibrary",
mounted() {
this.ctx = this.$refs.brushcanvas.getContext("2d");
this.delayRedrawCanvas();
},
data: () => ({
ctx: null,
redraw: true,
blocks: [],
}),
computed: {
currentAscii() {
return this.$store.getters.currentAscii;
},
toolbarState() {
return this.$store.getters.toolbarState;
},
isTargettingBg() {
return this.$store.getters.isTargettingBg;
},
isTargettingFg() {
return this.$store.getters.isTargettingFg;
},
isTargettingChar() {
return this.$store.getters.isTargettingChar;
},
currentFg() {
return this.$store.getters.currentFg;
},
currentBg() {
return this.$store.getters.currentBg;
},
currentChar() {
return this.$store.getters.currentChar;
},
brushSizeHeight() {
return this.$store.getters.brushSizeHeight;
},
brushSizeWidth() {
return this.$store.getters.brushSizeWidth;
},
brushSizeType() {
return this.$store.getters.brushSizeType;
},
mircColours() {
return mircColours99;
},
options() {
return this.$store.getters.options;
},
},
watch: {
brushSizeWidth() {
this.delayRedrawCanvas();
this.brushSizeWidthInput = this.brushSizeWidth;
},
brushSizeHeight() {
this.delayRedrawCanvas();
this.brushSizeHeightInput = this.brushSizeHeight;
},
brushSizeType() {
this.delayRedrawCanvas();
this.brushSizeTypeInput = this.brushSizeType;
},
isTargettingBg() {
this.delayRedrawCanvas();
},
isTargettingFg() {
this.delayRedrawCanvas();
},
isTargettingChar() {
this.delayRedrawCanvas();
},
currentFg() {
this.delayRedrawCanvas();
},
currentBg() {
this.delayRedrawCanvas();
},
currentChar() {
this.delayRedrawCanvas();
},
},
methods: {
updateBrushSize() {
this.$store.commit("updateBrushSize", {
brushSizeHeight: this.brushSizeHeightInput,
brushSizeWidth: this.brushSizeWidthInput,
brushSizeType: this.brushSizeTypeInput,
});
this.ctx.clearRect(0, 0, 10000, 10000);
this.delayRedrawCanvas();
},
drawPreview() {
this.ctx.clearRect(0, 0, 10000, 10000);
const brushHeight = this.brushSizeHeight;
const brushWidth = this.brushSizeWidth;
this.blocks = [];
this.ctx.fillStyle = this.mircColours[1];
const BLOCK_WIDTH = this.currentAscii.blockWidth;
const BLOCK_HEIGHT = this.currentAscii.blockHeight;
// hack font for ascii shout outs 2 beenz
this.ctx.font = "13px Hack";
let y = 0;
let x = 0;
let targetX = 0;
const block = {
fg: this.currentFg,
bg: this.currentBg,
char: this.currentChar,
};
const middleY = Math.floor(brushHeight / 2);
const middleX = Math.floor(brushWidth / 2);
let yModifier = 0;
// Recreate 2d array for preview
for (y = 0; y < brushHeight; y++) {
this.blocks[y] = [];
for (x = 0; x < brushWidth; x++) {
switch (this.brushSizeType) {
case "cross":
// If we are 1x1 force fill 1 block, to avoid an empty 1x1
if (x === 0 && y === 0) {
this.blocks[y][x] = { ...block };
continue;
}
if (x === brushWidth) {
this.blocks[y][x] = { ...emptyBlock };
} else {
this.blocks[y][x] = { ...block };
}
targetX = x;
if (y % 2 === 0) {
targetX -= 1;
}
if (this.blocks[y] && this.blocks[y][targetX]) {
if (x % 2 === 0) {
this.blocks[y][targetX] = { ...emptyBlock };
} else {
this.blocks[y][targetX] = { ...block };
}
}
break;
// default:
case "square":
this.blocks[y][x] = { ...block };
break;
case "circle":
if (middleY >= y) {
// Top half
yModifier = y;
if (x <= middleX + yModifier && x >= middleX - yModifier) {
this.blocks[y][x] = { ...block };
} else {
this.blocks[y][x] = { ...emptyBlock };
}
} else {
// Bottom half
yModifier = middleY - (y - middleY);
if (x <= middleX + yModifier && x >= middleX - yModifier) {
this.blocks[y][x] = { ...block };
} else {
this.blocks[y][x] = { ...emptyBlock };
}
}
break;
}
}
}
// Get middle block
for (y = 0; y < this.blocks.length; y++) {
for (x = 0; x < this.blocks[0].length; x++) {
if (this.blocks[y] && this.blocks[y][x]) {
const curBlock = this.blocks[y][x];
if (curBlock.bg && this.isTargettingBg) {
this.ctx.fillStyle = this.mircColours[curBlock.bg];
this.ctx.fillRect(
x * BLOCK_WIDTH,
y * BLOCK_HEIGHT,
BLOCK_WIDTH,
BLOCK_HEIGHT
);
}
if (curBlock.fg && this.isTargettingFg) {
this.ctx.fillStyle = this.mircColours[curBlock.fg];
}
if (curBlock.char && this.isTargettingChar) {
this.ctx.fillStyle = this.mircColours[curBlock.fg];
this.ctx.fillText(
curBlock.char,
x * BLOCK_WIDTH - 1,
y * BLOCK_HEIGHT + BLOCK_HEIGHT - 3
);
}
}
}
this.ctx.stroke();
this.$store.commit("brushBlocks", this.blocks);
}
},
delayRedrawCanvas() {
if (this.redraw) {
this.redraw = false;
setTimeout(() => {
this.redraw = true;
this.drawPreview();
}, this.options.canvasRedrawSpeed);
}
},
},
};
</script>

View File

@ -133,7 +133,7 @@ export default {
return this.$store.getters.currentBg;
},
currentChar() {
return this.$store.getters.getChar;
return this.$store.getters.currentChar;
},
isTextEditing() {
return this.currentTool.name === 'text';

View File

@ -156,7 +156,7 @@ export default {
return this.$store.getters.currentBg;
},
currentChar() {
return this.$store.getters.getChar;
return this.$store.getters.currentChar;
},
},
watch: {},

View File

@ -66,7 +66,6 @@ export default {
this.$modal.show("paste-ascii-modal");
},
close() {
console.log("close");
this.pasteContent = "";
this.title = "clipboard.txt";
this.$modal.hide("paste-ascii-modal");

View File

@ -0,0 +1,183 @@
<template>
<div>
<canvas
:ref="canvasName"
:id="canvasName"
:class="canvasName"
:width="brushSizeWidth * currentAscii.blockWidth"
:height="brushSizeHeight * currentAscii.blockHeight"
/>
</div>
</template>
<script>
import { mircColours99 } from "../../ascii";
export default {
name: "BrushCanvas",
mounted() {
this.ctx = this.$refs[this.canvasName].getContext("2d");
this.delayRedrawCanvas();
},
props: {
blocks: {
type: [Array, Boolean],
required: false,
default: false,
},
},
data: () => ({
ctx: null,
redraw: true,
}),
computed: {
currentAscii() {
return this.$store.getters.currentAscii;
},
toolbarState() {
return this.$store.getters.toolbarState;
},
isTargettingBg() {
return this.$store.getters.isTargettingBg;
},
isTargettingFg() {
return this.$store.getters.isTargettingFg;
},
isTargettingChar() {
return this.$store.getters.isTargettingChar;
},
currentFg() {
return this.$store.getters.currentFg;
},
currentBg() {
return this.$store.getters.currentBg;
},
currentChar() {
return this.$store.getters.currentChar;
},
brushSizeHeight() {
return this.$store.getters.brushSizeHeight;
},
brushSizeWidth() {
return this.$store.getters.brushSizeWidth;
},
brushSizeType() {
return this.$store.getters.brushSizeType;
},
options() {
return this.$store.getters.options;
},
canvasKey() {
return this.$store.getters.canvasKey + Math.round(Math.random()*1000);
},
canvasName() {
return `${this.canvasKey}-brush-canvas`;
},
getBlocks() {
return this.blocks === false
? this.$store.getters.brushBlocks
: this.blocks;
},
isMainCanvas() {
return this.blocks === false;
},
mircColours() {
return mircColours99;
},
},
watch: {
getBlocks() {
this.delayRedrawCanvas();
},
currentAscii() {
this.delayRedrawCanvas();
},
brushSizeHeight() {
this.delayRedrawCanvas();
},
brushSizeWidth() {
this.delayRedrawCanvas();
},
isTargettingBg() {
this.delayRedrawCanvas();
},
isTargettingFg() {
this.delayRedrawCanvas();
},
isTargettingChar() {
this.delayRedrawCanvas();
},
currentFg() {
this.delayRedrawCanvas();
},
currentBg() {
this.delayRedrawCanvas();
},
currentChar() {
this.delayRedrawCanvas();
},
},
methods: {
drawPreview() {
this.ctx.clearRect(0, 0, 10000, 10000);
this.ctx.fillStyle = this.mircColours[1];
const BLOCK_WIDTH = this.currentAscii.blockWidth;
const BLOCK_HEIGHT = this.currentAscii.blockHeight;
// hack font for ascii shout outs 2 beenz
this.ctx.font = "13px Hack";
let y = 0;
let x = 0;
// Get middle block
if (this.getBlocks) {
for (y = 0; y < this.getBlocks.length; y++) {
for (x = 0; x < this.getBlocks[0].length; x++) {
if (this.getBlocks[y] && this.getBlocks[y][x]) {
const curBlock = this.getBlocks[y][x];
if ((!this.isMainCanvas && curBlock.bg) || (curBlock.bg && this.isMainCanvas && this.isTargettingBg)) {
this.ctx.fillStyle = this.mircColours[(this.isMainCanvas ? this.currentBg : curBlock.bg)];
this.ctx.fillRect(
x * BLOCK_WIDTH,
y * BLOCK_HEIGHT,
BLOCK_WIDTH,
BLOCK_HEIGHT
);
}
if ((!this.isMainCanvas && curBlock.fg) || (curBlock.fg && this.isMainCanvas && this.isTargettingFg)) {
this.ctx.fillStyle = this.mircColours[(this.isMainCanvas ? this.currentFg : curBlock.fg)];
}
if ((!this.isMainCanvas && curBlock.char) || (curBlock.char && this.isMainCanvas && this.isTargettingChar)) {
this.ctx.fillStyle = this.mircColours[(this.isMainCanvas ? this.currentFg : curBlock.fg)];
this.ctx.fillText(
(this.isMainCanvas ? this.currentChar : curBlock.char),
x * BLOCK_WIDTH - 1,
y * BLOCK_HEIGHT + BLOCK_HEIGHT - 3
);
}
}
}
}
this.ctx.stroke();
}
},
delayRedrawCanvas() {
if (this.redraw) {
this.redraw = false;
setTimeout(() => {
this.redraw = true;
this.drawPreview();
}, this.options.canvasRedrawSpeed);
}
},
},
};
</script>

View File

@ -6,7 +6,6 @@
type="number"
name="width"
v-model="brushSizeWidthInput"
@change="updateBrushSize"
min="1"
max="10"
/>
@ -17,7 +16,6 @@
type="number"
name="height"
v-model="brushSizeHeightInput"
@change="updateBrushSize"
min="1"
max="10"
/>
@ -31,7 +29,6 @@
value="square"
checked
v-model="brushSizeTypeInput"
@change="updateBrushSize"
/>
<span class="text-sm">Square</span>
</label>
@ -41,7 +38,6 @@
name="options"
value="circle"
v-model="brushSizeTypeInput"
@change="updateBrushSize"
/>
<span class="text-sm">Circle</span>
</label>
@ -51,66 +47,46 @@
name="options"
value="cross"
v-model="brushSizeTypeInput"
@change="updateBrushSize"
/>
<span class="text-sm">Cross</span>
</label>
</div>
<canvas
ref="brushcanvas"
id="brushcanvas"
class="brushcanvas"
:width="brushSizeWidth * currentAscii.blockWidth"
:height="brushSizeHeight * currentAscii.blockHeight"
/>
<BrushCanvas />
</div>
</template>
<script>
import { emptyBlock, mircColours99 } from "../../ascii";
import { emptyBlock } from "../../ascii";
import BrushCanvas from "./BrushCanvas.vue"
export default {
name: "BrushPreview",
components: {
BrushCanvas,
},
mounted() {
this.ctx = this.$refs.brushcanvas.getContext("2d");
this.delayRedrawCanvas();
this.brushSizeWidthInput = this.brushSizeWidth;
this.brushSizeHeightInput = this.brushSizeHeight;
this.brushSizeTypeInput = this.brushSizeType;
this.createBlocks()
},
data: () => ({
ctx: null,
redraw: true,
blocks: [],
brushSizeHeightInput: 1,
brushSizeWidthInput: 1,
brushSizeTypeInput: "square",
}),
computed: {
currentAscii() {
return this.$store.getters.currentAscii;
},
toolbarState() {
return this.$store.getters.toolbarState;
},
isTargettingBg() {
return this.$store.getters.isTargettingBg;
},
isTargettingFg() {
return this.$store.getters.isTargettingFg;
},
isTargettingChar() {
return this.$store.getters.isTargettingChar;
},
currentFg() {
return this.$store.getters.currentFg;
},
currentBg() {
return this.$store.getters.currentBg;
},
getChar() {
return this.$store.getters.getChar;
currentChar() {
return this.$store.getters.currentChar;
},
brushSizeHeight() {
return this.$store.getters.brushSizeHeight;
@ -121,43 +97,34 @@ export default {
brushSizeType() {
return this.$store.getters.brushSizeType;
},
mircColours() {
return mircColours99;
},
options() {
return this.$store.getters.options;
},
currentAsciiBlocks() {
return this.$store.getters.currentAsciiBlocks
}
},
watch: {
brushSizeWidth() {
this.delayRedrawCanvas();
this.brushSizeWidthInput = this.brushSizeWidth;
},
brushSizeHeight() {
this.delayRedrawCanvas();
this.brushSizeHeightInput = this.brushSizeHeight;
},
brushSizeType() {
this.delayRedrawCanvas();
this.brushSizeTypeInput = this.brushSizeType;
},
isTargettingBg() {
this.delayRedrawCanvas();
brushSizeHeightInput(val, old) {
if (val !== old) {
this.createBlocks()
}
},
isTargettingFg() {
this.delayRedrawCanvas();
brushSizeWidthInput(val, old) {
if (val !== old) {
this.createBlocks()
}
},
isTargettingChar() {
this.delayRedrawCanvas();
},
currentFg() {
this.delayRedrawCanvas();
},
currentBg() {
this.delayRedrawCanvas();
},
getChar() {
this.delayRedrawCanvas();
brushSizeTypeInput(val, old) {
if (val !== old) {
this.createBlocks()
}
},
},
methods: {
@ -167,26 +134,14 @@ export default {
brushSizeWidth: this.brushSizeWidthInput,
brushSizeType: this.brushSizeTypeInput,
});
this.ctx.clearRect(0, 0, 10000, 10000);
this.delayRedrawCanvas();
},
drawPreview() {
this.ctx.clearRect(0, 0, 10000, 10000);
createBlocks() {
this.updateBrushSize()
const brushHeight = this.brushSizeHeight;
const brushWidth = this.brushSizeWidth;
this.blocks = [];
this.ctx.fillStyle = this.mircColours[1];
const BLOCK_WIDTH = this.currentAscii.blockWidth;
const BLOCK_HEIGHT = this.currentAscii.blockHeight;
// hack font for ascii shout outs 2 beenz
this.ctx.font = "13px Hack";
let y = 0;
let x = 0;
let targetX = 0;
@ -194,7 +149,7 @@ export default {
const block = {
fg: this.currentFg,
bg: this.currentBg,
char: this.getChar,
char: this.currentChar,
};
const middleY = Math.floor(brushHeight / 2);
@ -260,58 +215,13 @@ export default {
this.blocks[y][x] = { ...emptyBlock };
}
}
break;
}
}
}
// Get middle block
for (y = 0; y < this.blocks.length; y++) {
for (x = 0; x < this.blocks[0].length; x++) {
if (this.blocks[y] && this.blocks[y][x]) {
const curBlock = this.blocks[y][x];
if (curBlock.bg && this.isTargettingBg) {
this.ctx.fillStyle = this.mircColours[curBlock.bg];
this.ctx.fillRect(
x * BLOCK_WIDTH,
y * BLOCK_HEIGHT,
BLOCK_WIDTH,
BLOCK_HEIGHT
);
}
if (curBlock.fg && this.isTargettingFg) {
this.ctx.fillStyle = this.mircColours[curBlock.fg];
}
if (curBlock.char && this.isTargettingChar) {
this.ctx.fillStyle = this.mircColours[curBlock.fg];
this.ctx.fillText(
curBlock.char,
x * BLOCK_WIDTH - 1,
y * BLOCK_HEIGHT + BLOCK_HEIGHT - 3
);
}
}
}
this.ctx.stroke();
this.$store.commit("brushBlocks", this.blocks);
}
},
delayRedrawCanvas() {
if (this.redraw) {
this.redraw = false;
setTimeout(() => {
this.redraw = true;
this.drawPreview();
}, this.options.canvasRedrawSpeed);
}
this.$store.commit("brushBlocks", this.blocks)
},
},
};

View File

@ -15,6 +15,7 @@ const vuexLocal = new VuexPersistence({
export default new Vuex.Store({
state: {
key: 0,
modalState: {
newAscii: false,
editAscii: false,
@ -220,7 +221,7 @@ export default new Vuex.Store({
isTargettingChar: (state) => state.toolbarState.targetingChar,
currentFg: (state) => state.toolbarState.currentColourFg,
currentBg: (state) => state.toolbarState.currentColourBg,
getChar: (state) => state.toolbarState.selectedChar,
currentChar: (state) => state.toolbarState.selectedChar,
currentTab: (state) => state.tab,
currentAscii: (state) => state.asciibirdMeta[state.tab] ?? false,
currentAsciiBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[
@ -240,6 +241,10 @@ export default new Vuex.Store({
}
return false
},
canvasKey: (state) => {
state.key = state.key + 1;
return state.key
},
},
actions: {},
modules: {},

View File

@ -168,8 +168,8 @@ export default {
(this.brushSizeWidth < 10 && this.brushSizeWidth >= 1)) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: this.brushSizeHeight + 1,
brushSizeWidth: this.brushSizeWidth + 1,
brushSizeHeight: parseInt(this.brushSizeHeight) + 1,
brushSizeWidth: parseInt(this.brushSizeWidth) + 1,
brushSizeType: this.brushSizeType,
});
}
@ -179,8 +179,8 @@ export default {
(this.brushSizeWidth < 10 && this.brushSizeWidth >= 1)) {
this.$store.commit("updateBrushSize", {
brushSizeHeight: this.brushSizeHeight - 1,
brushSizeWidth: this.brushSizeWidth - 1,
brushSizeHeight: parseInt(this.brushSizeHeight) - 1,
brushSizeWidth: parseInt(this.brushSizeWidth) - 1,
brushSizeType: this.brushSizeType,
});
}
@ -253,7 +253,7 @@ export default {
return this.$store.getters.currentBg;
},
currentChar() {
return this.$store.getters.getChar;
return this.$store.getters.currentChar;
},
isTextEditing() {
return this.currentTool.name === 'text';

View File

@ -3,5 +3,7 @@ module.exports = {
css: {
extract: false
}
},
publicPath: ''
};