better char layout, same colour bg/fg and char improvement, 1000 fps, hotkeyable brushes and change position
Этот коммит содержится в:
родитель
5047b8faff
Коммит
cdfb31cc4c
|
@ -82,9 +82,8 @@ A most latest production build to use is available at https://asciibird.jewbird.
|
|||
|
||||
### Working on now
|
||||
|
||||
* If you drag a panel, then right click you can't drag it anymore
|
||||
* Unit testing
|
||||
* char panel has bg,fg when displaying chars, outline chars if same colours
|
||||
|
||||
### v 1.2
|
||||
|
||||
* More tooltips on other parts, at the moment only Toolbar has tooltips, option to disable tooltips
|
||||
|
@ -100,6 +99,7 @@ A most latest production build to use is available at https://asciibird.jewbird.
|
|||
* Context menus inside the panels can be way off sometimes
|
||||
* Main toolbar can sometimes get stuck and unmovable
|
||||
* Expand the brush manager, brush categories, download brushes, import/export brushes
|
||||
* Hotkeys for forst 10 brushes
|
||||
* ASCIIBIRD API ?!
|
||||
|
||||
## Mobile / Touch Screen support
|
||||
|
|
|
@ -496,7 +496,7 @@ export default {
|
|||
click: () => this.changeTab(i),
|
||||
|
||||
icon: "insert_drive_file",
|
||||
hotkey: `ctrl+${i}`,
|
||||
hotkey: `ctrl+shift+${i}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,10 +43,7 @@
|
|||
|
||||
<div class="flex">
|
||||
<div v-if="panel.tab === 0">
|
||||
<div
|
||||
v-for="(brush, key) in brushHistory"
|
||||
:key="key"
|
||||
>
|
||||
<div v-for="(brush, key) in brushHistory" :key="key">
|
||||
<t-card
|
||||
class="hover:border-blue-900 border-gray-300 bg-gray-200 mt-2"
|
||||
>
|
||||
|
@ -85,13 +82,13 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(brush, key) in brushLibrary"
|
||||
:key="key"
|
||||
>
|
||||
<div v-for="(brush, key) in brushLibrary" :key="key">
|
||||
<t-card
|
||||
:class="`hover:border-blue-900 border-gray-300 bg-gray-200 mt-2`"
|
||||
>
|
||||
<small v-if="key <= 9"
|
||||
>Ctrl+{{ key === 9 ? 0 : key + 1 }}</small
|
||||
>
|
||||
<BrushCanvas :blocks="decompressBlock(brush.blocks)" />
|
||||
|
||||
<t-button
|
||||
|
@ -108,6 +105,24 @@
|
|||
>
|
||||
<span class="material-icons">brush</span>
|
||||
</t-button>
|
||||
|
||||
<t-button
|
||||
v-if="key !== 0"
|
||||
type="button"
|
||||
class="ab-rounded-button ml-1 mt-1"
|
||||
@click="upBrush(key)"
|
||||
>
|
||||
<span class="material-icons">arrow_upward</span>
|
||||
</t-button>
|
||||
|
||||
<t-button
|
||||
type="button"
|
||||
class="ab-rounded-button ml-1 mt-1"
|
||||
@click="downBrush(key)"
|
||||
v-if="key !== brushLibrary.length-1"
|
||||
>
|
||||
<span class="material-icons">arrow_downward</span>
|
||||
</t-button>
|
||||
</t-card>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -128,7 +143,7 @@
|
|||
</style>
|
||||
|
||||
<script>
|
||||
import { mircColours99, blockWidth, blockHeight } from "../ascii";
|
||||
import { mircColours99, blockWidth, blockHeight, toolbarIcons } from "../ascii";
|
||||
import BrushCanvas from "./parts/BrushCanvas.vue";
|
||||
import LZString from "lz-string";
|
||||
|
||||
|
@ -140,6 +155,21 @@ export default {
|
|||
this.panel.w = this.brushLibraryState.w;
|
||||
this.panel.h = this.brushLibraryState.h;
|
||||
this.panel.tab = this.brushLibraryState.tab;
|
||||
|
||||
var _this = this;
|
||||
hotkeys(`${this.hotkeyBrushes}`, async function (event, handler) {
|
||||
event.preventDefault();
|
||||
|
||||
if (_this.isBrushing || _this.isErasing) {
|
||||
let brushSelect =
|
||||
Number.parseInt(event.key) !== 0 ? Number.parseInt(event.key) - 1 : 9;
|
||||
if (_this.brushLibrary[brushSelect]) {
|
||||
_this.reuseBlocks(
|
||||
_this.decompressBlock(_this.brushLibrary[brushSelect].blocks)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
data: () => ({
|
||||
panel: {
|
||||
|
@ -157,6 +187,13 @@ export default {
|
|||
},
|
||||
props: ["yOffset"],
|
||||
computed: {
|
||||
hotkeyBrushes() {
|
||||
let hotkeyString = "";
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
hotkeyString = `${hotkeyString}ctrl+${i},`;
|
||||
}
|
||||
return hotkeyString;
|
||||
},
|
||||
blockWidth() {
|
||||
return blockWidth * this.blockSizeMultiplier;
|
||||
},
|
||||
|
@ -189,6 +226,18 @@ export default {
|
|||
? `(${this.brushLibrary.length})`
|
||||
: "";
|
||||
},
|
||||
toolbarIcons() {
|
||||
return toolbarIcons;
|
||||
},
|
||||
currentTool() {
|
||||
return toolbarIcons[this.$store.getters.currentTool];
|
||||
},
|
||||
isBrushing() {
|
||||
return this.currentTool.name === "brush";
|
||||
},
|
||||
isErasing() {
|
||||
return this.currentTool.name === "eraser";
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
yOffset(val) {
|
||||
|
@ -226,6 +275,12 @@ export default {
|
|||
this.$store.commit("removeBrushHistory", value);
|
||||
this.$toasted.show(`Removed brush from History`);
|
||||
},
|
||||
upBrush(key) {
|
||||
this.$store.commit("upBrush", key);
|
||||
},
|
||||
downBrush(key) {
|
||||
this.$store.commit("downBrush", key);
|
||||
},
|
||||
onResize(x, y, w, h) {
|
||||
this.panel.x = x;
|
||||
this.panel.y = y;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<t-button
|
||||
type="button"
|
||||
:style="`background-color: ${mircColours[currentBg]} !important;color: ${mircColours[currentFg]};`"
|
||||
:style="`background-color: ${mircColours[currentBg]} !important;color: ${mircColours[currentFg]};${outline}`"
|
||||
class="border-gray-200 w-14 h-14 text-2xl ml-14"
|
||||
id="currentChar"
|
||||
@click="
|
||||
|
@ -63,6 +63,14 @@ export default {
|
|||
currentBg() {
|
||||
return this.$store.getters.currentBg;
|
||||
},
|
||||
outline() {
|
||||
let outlineColor = this.currentBg === 0 ? 'black' : 'white';
|
||||
if (this.currentFg === this.currentBg) {
|
||||
return `-webkit-text-stroke-width: 0.5px;-webkit-text-stroke-color: ${outlineColor};`;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
swapColours() {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
v-model="options.fps"
|
||||
@dragend="updateOptions"
|
||||
:min="1"
|
||||
:max="200"
|
||||
:max="1000"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<vue-draggable-resizable
|
||||
:x="100"
|
||||
:x="170"
|
||||
:y="100+yOffset"
|
||||
:w="1100"
|
||||
:w="650"
|
||||
:h="350"
|
||||
>
|
||||
<t-card class="w-full h-full">
|
||||
|
@ -10,17 +10,18 @@
|
|||
type="button"
|
||||
v-for="(char, keyChar) in charCodes"
|
||||
:key="keyChar"
|
||||
class="border-gray-200 p-2 min-h-0"
|
||||
:style="`background-color: ${mircColours[currentBg]} !important;color: ${mircColours[currentFg]} !important;${outline};font-size: 13px;width: ${blockWidth}px;height: ${blockHeight}px;`"
|
||||
class="m-0.5"
|
||||
@click="onCharChange(char)"
|
||||
>
|
||||
{{ char === " " ? "space" : char }}
|
||||
{{ char === " " ? "SP" : char }}
|
||||
</t-button>
|
||||
</t-card>
|
||||
</vue-draggable-resizable>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { charCodes } from "../../ascii";
|
||||
import { charCodes, mircColours99, blockWidth, blockHeight } from "../../ascii";
|
||||
|
||||
export default {
|
||||
name: "CharPicker",
|
||||
|
@ -30,6 +31,29 @@ export default {
|
|||
charCodes() {
|
||||
return charCodes;
|
||||
},
|
||||
mircColours() {
|
||||
return mircColours99;
|
||||
},
|
||||
currentFg() {
|
||||
return this.$store.getters.currentFg;
|
||||
},
|
||||
currentBg() {
|
||||
return this.$store.getters.currentBg;
|
||||
},
|
||||
outline() {
|
||||
let outlineColor = this.currentBg === 0 ? 'black' : 'white';
|
||||
if (this.currentFg === this.currentBg) {
|
||||
return `-webkit-text-stroke-width: 0.5px;-webkit-text-stroke-color: ${outlineColor};`;
|
||||
}
|
||||
|
||||
return "";
|
||||
},
|
||||
blockWidth() {
|
||||
return blockWidth*2;
|
||||
},
|
||||
blockHeight() {
|
||||
return blockHeight*2;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onCharChange(char) {
|
||||
|
|
|
@ -383,22 +383,6 @@ export default new Vuex.Store({
|
|||
|
||||
tempLayers.splice(payload, 1)
|
||||
|
||||
// Remove our undos here for the layer
|
||||
// let history = state.asciibirdMeta[state.tab].history;
|
||||
|
||||
// for (let i in history) {
|
||||
// if (history[i].t !== undefined && history[i].t === 'l') {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// let data = JSON.parse(LZString.decompressFromUTF16(history[i]));
|
||||
|
||||
// if (data.l === payload) {
|
||||
// history.splice(i, 1);
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// Automatically select the next best layer to avoid bugs
|
||||
let selectedLayer = state.asciibirdMeta[state.tab].selectedLayer
|
||||
|
||||
|
@ -424,6 +408,28 @@ export default new Vuex.Store({
|
|||
}
|
||||
|
||||
},
|
||||
upBrush(state, key) {
|
||||
let tempBrushLibrary = [ ... state.brushLibrary];
|
||||
|
||||
let swap1 = tempBrushLibrary[key - 1];
|
||||
let swap = tempBrushLibrary[key];
|
||||
|
||||
tempBrushLibrary[key - 1] = swap
|
||||
tempBrushLibrary[key] = swap1
|
||||
|
||||
state.brushLibrary = tempBrushLibrary
|
||||
},
|
||||
downBrush(state, key) {
|
||||
let tempBrushLibrary = [ ... state.brushLibrary];
|
||||
|
||||
let swap1 = tempBrushLibrary[key + 1];
|
||||
let swap = tempBrushLibrary[key];
|
||||
|
||||
tempBrushLibrary[key + 1] = swap
|
||||
tempBrushLibrary[key] = swap1
|
||||
|
||||
state.brushLibrary = tempBrushLibrary
|
||||
},
|
||||
downLayer(state, payload) {
|
||||
let tempLayers = JSON.parse(LZString.decompressFromUTF16(state.asciibirdMeta[state.tab]
|
||||
.layers))
|
||||
|
@ -437,22 +443,6 @@ export default new Vuex.Store({
|
|||
tempLayers[payload + 1] = swap
|
||||
tempLayers[payload] = swap1
|
||||
|
||||
// Remove our undos here for the layer
|
||||
// let history = state.asciibirdMeta[state.tab].history;
|
||||
|
||||
// for (let i in history) {
|
||||
// if (history[i].t !== undefined && history[i].t === 'l') {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// let data = JSON.parse(LZString.decompressFromUTF16(history[i]));
|
||||
|
||||
// if (data.l === payload) {
|
||||
// data.l === payload + 1;
|
||||
// history[i] = LZString.compressToUTF16(JSON.stringify(data));
|
||||
// }
|
||||
// }
|
||||
|
||||
state.asciibirdMeta[state.tab].layers = LZString.compressToUTF16(JSON.stringify(
|
||||
tempLayers));
|
||||
|
||||
|
@ -484,22 +474,6 @@ export default new Vuex.Store({
|
|||
tempLayers[payload - 1] = swap
|
||||
tempLayers[payload] = swap1
|
||||
|
||||
// Remove our undos here for the layer
|
||||
// let history = state.asciibirdMeta[state.tab].history;
|
||||
|
||||
// for (let i in history) {
|
||||
// if (history[i].t !== undefined && history[i].t === 'l') {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// let data = JSON.parse(LZString.decompressFromUTF16(history[i]));
|
||||
|
||||
// if (data.l === payload) {
|
||||
// data.l === payload - 1;
|
||||
// history[i] = LZString.compressToUTF16(JSON.stringify(data));
|
||||
// }
|
||||
// }
|
||||
|
||||
state.asciibirdMeta[state.tab].layers = LZString.compressToUTF16(JSON.stringify(
|
||||
tempLayers));
|
||||
|
||||
|
@ -543,30 +517,10 @@ export default new Vuex.Store({
|
|||
.length;
|
||||
}
|
||||
},
|
||||
|
||||
// ASCII
|
||||
updateAsciiTitle(state, payload) {
|
||||
state.asciibirdMeta[state.tab].title = payload;
|
||||
},
|
||||
|
||||
|
||||
// pushLayerHistory(state, payload) {
|
||||
// let historyIndex = state.asciibirdMeta[state.tab].historyIndex;
|
||||
|
||||
// payload = payload.map(function(item) {
|
||||
// delete item['data']
|
||||
// return item;
|
||||
// });
|
||||
|
||||
// let layerHistory = LZString.compressToUTF16(JSON.stringify({
|
||||
// t: 'l',
|
||||
// o: payload.old,
|
||||
// n: payload.new
|
||||
// }));
|
||||
|
||||
// state.asciibirdMeta[state.tab].history.push(layerHistory)
|
||||
// },
|
||||
|
||||
// BLOCKS
|
||||
undoBlocks(state) {
|
||||
let historyIndex = state.asciibirdMeta[state.tab].historyIndex;
|
||||
|
|
|
@ -14,6 +14,13 @@ import hotkeysImport from 'hotkeys-js';
|
|||
const localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
|
||||
// Test cases will cover most of asciibirds stuff
|
||||
// Make new ascii
|
||||
// Import ascii
|
||||
// Change tabs ?
|
||||
// Whatever tools on both
|
||||
|
||||
|
||||
describe('Editor.vue', () => {
|
||||
let actions
|
||||
let state
|
||||
|
@ -40,6 +47,8 @@ describe('Editor.vue', () => {
|
|||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
it('create new ascii data is as expected', () => {
|
||||
|
@ -73,4 +82,5 @@ describe('Editor.vue', () => {
|
|||
"selectedLayer": 0
|
||||
});
|
||||
})
|
||||
|
||||
})
|
||||
|
|
Загрузка…
Ссылка в новой задаче