toolbar ui update, bug fix
这个提交包含在:
父节点
698ed576a1
当前提交
c61144acf1
10
README.md
10
README.md
|
@ -20,8 +20,6 @@
|
|||
* Redo (ctrl y) is a buggy
|
||||
* Circle brush (works okay for odd width and height numbers)
|
||||
* Select only works from dragging top left to bottom right, not the other way around
|
||||
* Resizing the canvas a certain way wont make new blocks
|
||||
* No undo using text tool
|
||||
* Brush cannot brush row 0 in mirror mode
|
||||
# FOCUSING ON NOW
|
||||
|
||||
|
@ -52,8 +50,8 @@
|
|||
# Keyboard Shortcuts
|
||||
|
||||
* Ctrl D - shows/hides debug panel
|
||||
* Ctrl Z - Undo (sometimes have to press twice)
|
||||
* Ctrl Y - Redo (sometimes have to press twice)
|
||||
* Ctrl Z - Undo
|
||||
* Ctrl Y - Redo
|
||||
|
||||
# FEATURES DONE
|
||||
|
||||
|
@ -78,10 +76,6 @@
|
|||
|
||||
* Insert image to convert to ASCII into a layer
|
||||
* Support for tdfiglet, toilet, figlet importing
|
||||
|
||||
# Things To Do Later
|
||||
|
||||
* Properly get CSS into the JS stuff ya lazy bird
|
||||
# References
|
||||
|
||||
* https://jp.itch.io/playscii / http://vectorpoem.com/playscii/
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<t-card>
|
||||
<div>
|
||||
<t-button
|
||||
type="button"
|
||||
:style="`background-color: ${mircColours[currentFg]} !important;`"
|
||||
class="border-gray-200 p-1"
|
||||
class="border-gray-200 p-3 w-14 h-14 text-2xl"
|
||||
id="currentColourFg"
|
||||
@click="$store.commit('changeIsUpdatingFg', true)"
|
||||
>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<t-button
|
||||
type="button"
|
||||
:style="`background-color: ${mircColours[currentBg]} !important;`"
|
||||
class="border-gray-200 p-1"
|
||||
class="border-gray-200 p-3 w-14 h-14 text-2xl"
|
||||
id="currentColourBg"
|
||||
@click="$store.commit('changeIsUpdatingBg', true)"
|
||||
>
|
||||
|
@ -22,30 +22,31 @@
|
|||
|
||||
<t-button
|
||||
type="button"
|
||||
class="p-1 bg-white"
|
||||
class="bg-white absolute rounded-full"
|
||||
style="margin-left: -67px; margin-top: 15px"
|
||||
id="swapColour"
|
||||
@click="swapColours()"
|
||||
>
|
||||
<font-awesome-icon :icon="['fas', 'sync']" />
|
||||
<font-awesome-icon :icon="['fas', 'sync']" size="lg"/>
|
||||
</t-button>
|
||||
|
||||
<t-button
|
||||
type="button"
|
||||
:style="`background-color: ${mircColours[currentBg]} !important;color: ${mircColours[currentFg]};`"
|
||||
class="border-gray-200 p-1 w-8 h-8"
|
||||
class="border-gray-200 p-3 w-14 h-14 text-2xl"
|
||||
id="currentChar"
|
||||
@click="$store.commit('changeIsUpdatingChar', true)"
|
||||
>
|
||||
{{ toolbarState.selectedChar }}
|
||||
{{ toolbarState.selectedChar === " " ? "SP" : toolbarState.selectedChar }}
|
||||
</t-button>
|
||||
</t-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mircColours99 } from '../ascii';
|
||||
import { mircColours99 } from "../ascii";
|
||||
|
||||
export default {
|
||||
name: 'Colours',
|
||||
name: "Colours",
|
||||
data: () => ({}),
|
||||
computed: {
|
||||
mircColours() {
|
||||
|
@ -66,8 +67,8 @@ export default {
|
|||
const bg = this.currentBg;
|
||||
const fg = this.currentFg;
|
||||
|
||||
this.$store.commit('changeColourFg', bg);
|
||||
this.$store.commit('changeColourBg', fg);
|
||||
this.$store.commit("changeColourFg", bg);
|
||||
this.$store.commit("changeColourBg", fg);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -14,70 +14,81 @@
|
|||
:y="toolbarState.y"
|
||||
>
|
||||
<t-card style="height: 100%">
|
||||
<label class="flex ml-1">
|
||||
<t-checkbox
|
||||
name="targetingFg"
|
||||
v-model="toolbarState.targetingFg"
|
||||
:disabled="!canBg && !canText"
|
||||
/>
|
||||
<span class="text-sm">FG</span>
|
||||
</label>
|
||||
<label class="flex ml-1">
|
||||
<t-checkbox
|
||||
name="targetingBg"
|
||||
v-model="toolbarState.targetingBg"
|
||||
:disabled="!canFg && !canText"
|
||||
checked
|
||||
/>
|
||||
<span class="text-sm">BG</span>
|
||||
</label>
|
||||
<label class="flex ml-1">
|
||||
<t-checkbox
|
||||
name="targetingChar"
|
||||
v-model="toolbarState.targetingChar"
|
||||
:disabled="!canFg && !canBg"
|
||||
/>
|
||||
<span class="text-sm">Text</span>
|
||||
</label>
|
||||
<Colours />
|
||||
|
||||
<hr>
|
||||
|
||||
<label class="flex ml-1">
|
||||
<t-checkbox
|
||||
name="targetingFg"
|
||||
v-model="mirror.x"
|
||||
@change="updateMirror()"
|
||||
/>
|
||||
<span class="text-sm">Mirror X</span>
|
||||
</label>
|
||||
<label class="flex ml-1">
|
||||
<t-checkbox
|
||||
name="targetingBg"
|
||||
v-model="mirror.y"
|
||||
@change="updateMirror()"
|
||||
/>
|
||||
<span class="text-sm">Mirror Y</span>
|
||||
</label>
|
||||
|
||||
<hr>
|
||||
<div class="flex">
|
||||
<label class="ml-1 w-1/3">
|
||||
<t-checkbox
|
||||
name="targetingFg"
|
||||
v-model="toolbarState.targetingFg"
|
||||
:disabled="!canBg && !canText"
|
||||
/>
|
||||
<span class="text-sm">FG</span>
|
||||
</label>
|
||||
|
||||
<Colours />
|
||||
<label class="ml-1 w-1/3">
|
||||
<t-checkbox
|
||||
name="targetingBg"
|
||||
v-model="toolbarState.targetingBg"
|
||||
:disabled="!canFg && !canText"
|
||||
checked
|
||||
/>
|
||||
<span class="text-sm">BG</span>
|
||||
</label>
|
||||
|
||||
<label class="ml-1 w-1/3">
|
||||
<t-checkbox
|
||||
name="targetingChar"
|
||||
v-model="toolbarState.targetingChar"
|
||||
:disabled="!canFg && !canBg"
|
||||
/>
|
||||
<span class="text-sm">Text</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<hr class="m-3" />
|
||||
|
||||
<t-button
|
||||
type="button"
|
||||
v-for="(value, keyToolbar) in toolbarIcons"
|
||||
:key="keyToolbar + 50"
|
||||
:class="`max-h-7 max-w-5 w-7 ${
|
||||
:class="`w-10 h-10 ${
|
||||
currentTool.name === value.name
|
||||
? 'border-gray-900'
|
||||
: 'border-gray-200'
|
||||
? 'border-gray-900 bg-blue-500'
|
||||
: 'border-gray-200 bg-gray-500'
|
||||
}`"
|
||||
@click="$store.commit('changeTool', keyToolbar)"
|
||||
>
|
||||
<font-awesome-icon :icon="[value.fa, value.icon]" />
|
||||
</t-button>
|
||||
|
||||
<hr>
|
||||
<hr class="m-3" />
|
||||
|
||||
|
||||
<div class="flex">
|
||||
<label class="ml-1 w-1/2">
|
||||
<t-checkbox
|
||||
name="targetingFg"
|
||||
v-model="mirror.x"
|
||||
@change="updateMirror()"
|
||||
/>
|
||||
<span class="text-sm">Mirror X</span>
|
||||
</label>
|
||||
<label class="ml-1 w-1/2">
|
||||
<t-checkbox
|
||||
name="targetingBg"
|
||||
v-model="mirror.y"
|
||||
@change="updateMirror()"
|
||||
/>
|
||||
<span class="text-sm">Mirror Y</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<hr class="m-2" />
|
||||
|
||||
|
||||
|
||||
<BrushPreview />
|
||||
</t-card>
|
||||
|
@ -86,9 +97,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Colours from './Colours.vue';
|
||||
import BrushPreview from './parts/BrushPreview.vue';
|
||||
import { toolbarIcons } from '../ascii';
|
||||
import Colours from "./Colours.vue";
|
||||
import BrushPreview from "./parts/BrushPreview.vue";
|
||||
import { toolbarIcons } from "../ascii";
|
||||
|
||||
export default {
|
||||
created() {
|
||||
|
@ -100,7 +111,7 @@ export default {
|
|||
this.mirror.x = this.toolbarState.mirrorX;
|
||||
this.mirror.y = this.toolbarState.mirrorY;
|
||||
},
|
||||
name: 'Toolbar',
|
||||
name: "Toolbar",
|
||||
components: { Colours, BrushPreview },
|
||||
|
||||
data: () => ({
|
||||
|
@ -150,7 +161,7 @@ export default {
|
|||
watch: {},
|
||||
methods: {
|
||||
updateMirror() {
|
||||
this.$store.commit('updateMirror', this.mirror);
|
||||
this.$store.commit("updateMirror", this.mirror);
|
||||
},
|
||||
onResize(x, y, w, h) {
|
||||
this.toolbar.x = x;
|
||||
|
@ -158,7 +169,7 @@ export default {
|
|||
this.toolbar.w = w;
|
||||
this.toolbar.h = h;
|
||||
|
||||
this.$store.commit('changeToolBarState', {
|
||||
this.$store.commit("changeToolBarState", {
|
||||
x,
|
||||
y,
|
||||
w: this.toolbar.w,
|
||||
|
@ -169,7 +180,7 @@ export default {
|
|||
this.toolbar.x = x;
|
||||
this.toolbar.y = y;
|
||||
|
||||
this.$store.commit('changeToolBarState', {
|
||||
this.$store.commit("changeToolBarState", {
|
||||
x,
|
||||
y,
|
||||
w: this.toolbar.w,
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
<template>
|
||||
<div>
|
||||
<t-input
|
||||
type="number"
|
||||
name="width"
|
||||
v-model="brushSizeWidth"
|
||||
@change="updateBrushSize"
|
||||
min="1"
|
||||
max="10"
|
||||
/>
|
||||
<div class="flex">
|
||||
<div class="w-1/2">
|
||||
<t-input
|
||||
type="number"
|
||||
name="width"
|
||||
v-model="brushSizeWidth"
|
||||
@change="updateBrushSize"
|
||||
min="1"
|
||||
max="10"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<t-input
|
||||
type="number"
|
||||
name="height"
|
||||
v-model="brushSizeHeight"
|
||||
@change="updateBrushSize"
|
||||
min="1"
|
||||
max="10"
|
||||
/>
|
||||
<div class="w-1/2">
|
||||
<t-input
|
||||
type="number"
|
||||
name="height"
|
||||
v-model="brushSizeHeight"
|
||||
@change="updateBrushSize"
|
||||
min="1"
|
||||
max="10"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<label class="block">
|
||||
|
@ -62,12 +68,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { emptyBlock, mircColours99 } from '../../ascii';
|
||||
import { emptyBlock, mircColours99 } from "../../ascii";
|
||||
|
||||
export default {
|
||||
name: 'BrushPreview',
|
||||
name: "BrushPreview",
|
||||
mounted() {
|
||||
this.ctx = this.$refs.brushcanvas.getContext('2d');
|
||||
this.ctx = this.$refs.brushcanvas.getContext("2d");
|
||||
this.delayRedrawCanvas();
|
||||
this.brushSizeWidth = this.brushSizeWidthPreview;
|
||||
this.brushSizeHeight = this.brushSizeHeightPreview;
|
||||
|
@ -79,7 +85,7 @@ export default {
|
|||
blocks: [],
|
||||
brushSizeHeight: 1,
|
||||
brushSizeWidth: 1,
|
||||
brushSizeType: 'square',
|
||||
brushSizeType: "square",
|
||||
}),
|
||||
computed: {
|
||||
currentAscii() {
|
||||
|
@ -118,6 +124,9 @@ export default {
|
|||
mircColours() {
|
||||
return mircColours99;
|
||||
},
|
||||
options() {
|
||||
return this.$store.getters.options;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
brushSizeWidth() {
|
||||
|
@ -147,7 +156,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
updateBrushSize() {
|
||||
this.$store.commit('updateBrushSize', {
|
||||
this.$store.commit("updateBrushSize", {
|
||||
brushSizeHeight: this.brushSizeHeight,
|
||||
brushSizeWidth: this.brushSizeWidth,
|
||||
brushSizeType: this.brushSizeType,
|
||||
|
@ -170,7 +179,7 @@ export default {
|
|||
const BLOCK_HEIGHT = this.currentAscii.blockHeight;
|
||||
|
||||
// hack font for ascii shout outs 2 beenz
|
||||
this.ctx.font = '13px Hack';
|
||||
this.ctx.font = "13px Hack";
|
||||
|
||||
let y = 0;
|
||||
let x = 0;
|
||||
|
@ -191,7 +200,7 @@ export default {
|
|||
this.blocks[y] = [];
|
||||
for (x = 0; x < brushWidth; x++) {
|
||||
switch (this.brushSizeTypePreview) {
|
||||
case 'cross':
|
||||
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 };
|
||||
|
@ -221,11 +230,11 @@ export default {
|
|||
break;
|
||||
|
||||
// default:
|
||||
case 'square':
|
||||
case "square":
|
||||
this.blocks[y][x] = { ...block };
|
||||
break;
|
||||
|
||||
case 'circle':
|
||||
case "circle":
|
||||
if (middleY >= y) {
|
||||
// Top half
|
||||
yModifier = y;
|
||||
|
@ -264,7 +273,7 @@ export default {
|
|||
x * BLOCK_WIDTH,
|
||||
y * BLOCK_HEIGHT,
|
||||
BLOCK_WIDTH,
|
||||
BLOCK_HEIGHT,
|
||||
BLOCK_HEIGHT
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -277,7 +286,7 @@ export default {
|
|||
this.ctx.fillText(
|
||||
curBlock.char,
|
||||
x * BLOCK_WIDTH - 1,
|
||||
y * BLOCK_HEIGHT + BLOCK_HEIGHT - 3,
|
||||
y * BLOCK_HEIGHT + BLOCK_HEIGHT - 3
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +294,7 @@ export default {
|
|||
|
||||
this.ctx.stroke();
|
||||
|
||||
this.$store.commit('brushBlocks', this.blocks);
|
||||
this.$store.commit("brushBlocks", this.blocks);
|
||||
}
|
||||
},
|
||||
delayRedrawCanvas() {
|
||||
|
@ -295,7 +304,7 @@ export default {
|
|||
setTimeout(() => {
|
||||
this.redraw = true;
|
||||
this.drawPreview();
|
||||
}, 2);
|
||||
}, this.options.canvasRedrawSpeed);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ export default new Vuex.Store({
|
|||
// The various options of ASCIIBIRD will eventually
|
||||
// end up in its own modal I guess
|
||||
options: {
|
||||
canvasRedrawSpeed: 2,
|
||||
canvasRedrawSpeed: 50,
|
||||
defaultBg: 1,
|
||||
defaultFg: 0,
|
||||
},
|
||||
|
@ -204,8 +204,7 @@ export default new Vuex.Store({
|
|||
getChar: (state) => state.toolbarState.selectedChar,
|
||||
currentTab: (state) => state.tab,
|
||||
currentAscii: (state) => state.asciibirdMeta[state.tab] ?? false,
|
||||
currentAsciiBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
|
||||
.blocks)) || [],
|
||||
currentAsciiBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab].blocks)) || [],
|
||||
asciibirdMeta: (state) => state.asciibirdMeta,
|
||||
nextTabValue: (state) => state.asciibirdMeta.length,
|
||||
brushSizeHeight: (state) => state.toolbarState.brushSizeHeight,
|
||||
|
|
|
@ -351,40 +351,30 @@ export default {
|
|||
onCanvasResize(left, top, width, height) {
|
||||
const blocks = this.currentAsciiBlocks;
|
||||
|
||||
const oldWidth = blocks[0].length;
|
||||
const oldHeight = blocks.length;
|
||||
|
||||
const canvasBlockHeight = Math.floor(
|
||||
height / this.currentAscii.blockHeight,
|
||||
);
|
||||
const canvasBlockWidth = Math.floor(width / this.currentAscii.blockWidth);
|
||||
|
||||
if (canvasBlockHeight > oldHeight || canvasBlockWidth > oldWidth) {
|
||||
// console.log({ canvasBlockHeight, oldHeight });
|
||||
|
||||
for (let y = 0; y < canvasBlockHeight; y++) {
|
||||
// New row
|
||||
if (!blocks[y]) {
|
||||
blocks[y] = [];
|
||||
for (let x = 0; x < canvasBlockWidth; x++) {
|
||||
// Previously we had an if statement to check if we needed new blocks
|
||||
// removed it so we can get all blocks always
|
||||
for (let y = 0; y < canvasBlockHeight; y++) {
|
||||
// New row
|
||||
if (!blocks[y]) {
|
||||
blocks[y] = [];
|
||||
for (let x = 0; x < canvasBlockWidth; x++) {
|
||||
blocks[y][x] = { ...emptyBlock };
|
||||
}
|
||||
} else {
|
||||
// no new rows but new cols
|
||||
for (let x = 0; x < canvasBlockWidth; x++) {
|
||||
if (blocks[y] && !blocks[y][x]) {
|
||||
blocks[y][x] = { ...emptyBlock };
|
||||
}
|
||||
} else {
|
||||
// blocks[y]
|
||||
// no new rows but new cols
|
||||
for (let x = 0; x < canvasBlockWidth; x++) {
|
||||
if (blocks[y] && !blocks[y][x]) {
|
||||
blocks[y][x] = { ...emptyBlock };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canvasBlockWidth > oldWidth) {
|
||||
// console.log({ canvasBlockWidth, oldWidth });
|
||||
}
|
||||
|
||||
this.canvas.width = width;
|
||||
this.canvas.height = height;
|
||||
|
||||
|
@ -394,7 +384,7 @@ export default {
|
|||
});
|
||||
|
||||
this.$store.commit('updateAsciiBlocks', blocks);
|
||||
// Restructure blocks code here
|
||||
|
||||
this.delayRedrawCanvas();
|
||||
},
|
||||
onCavasDragStop(x, y) {
|
||||
|
|
正在加载...
在新工单中引用