better modals, keyboard input in modals, new keyboard shortcuts
This commit is contained in:
parent
014ad5602b
commit
d2f38f822c
18
README.md
18
README.md
|
@ -49,9 +49,21 @@
|
|||
|
||||
# Keyboard Shortcuts
|
||||
|
||||
* Ctrl D - shows/hides debug panel
|
||||
* Ctrl Z - Undo
|
||||
* Ctrl Y - Redo
|
||||
## ASCII Editing
|
||||
|
||||
* Ctrl + D - shows/hides debug panel
|
||||
* Ctrl + Z - Undo
|
||||
* Ctrl + Y - Redo
|
||||
* Ctrl + M - New ASCII (lol @ cannot override ctrl n ?!)
|
||||
* Ctrl + E - Edit ASCII
|
||||
* Ctrl + P - Paste ASCII from Clipboard
|
||||
|
||||
* Ctrl + Shift + C - Save to clipboard
|
||||
* Ctrl + Shift + F - Save to txt file
|
||||
## Brush and Toolbar
|
||||
|
||||
* Ctrl + ] - Increase brush size
|
||||
* Ctrl + [ - Decrease brush size
|
||||
|
||||
# FEATURES DONE
|
||||
|
||||
|
|
|
@ -4,10 +4,7 @@
|
|||
<EditAscii />
|
||||
<PasteAscii />
|
||||
|
||||
<context-menu
|
||||
:display="showContextMenu"
|
||||
ref="menu"
|
||||
>
|
||||
<context-menu :display="showContextMenu" ref="menu">
|
||||
<ul>
|
||||
<li
|
||||
@click="$store.commit('openModal', 'new-ascii')"
|
||||
|
@ -16,34 +13,21 @@
|
|||
>
|
||||
New ASCII
|
||||
</li>
|
||||
<li @click="clearCache()" class="ml-1">Clear and Refresh</li>
|
||||
<li @click="startImport('mirc')" class="ml-1">Import mIRC</li>
|
||||
<li
|
||||
@click="clearCache()"
|
||||
class="ml-1"
|
||||
>
|
||||
Clear and Refresh
|
||||
</li>
|
||||
<li
|
||||
@click="startImport('mirc')"
|
||||
class="ml-1"
|
||||
>
|
||||
Import mIRC
|
||||
</li>
|
||||
<li
|
||||
@click="exportMirc('file')"
|
||||
@click="startExport('file')"
|
||||
class="ml-1"
|
||||
v-if="asciibirdMeta.length"
|
||||
>
|
||||
Export mIRC to File
|
||||
</li>
|
||||
<li
|
||||
class="ml-1"
|
||||
@click="$store.commit('openModal', 'paste-modal')"
|
||||
>
|
||||
<li class="ml-1" @click="$store.commit('openModal', 'paste-ascii')">
|
||||
Import mIRC from Clipboard
|
||||
</li>
|
||||
<li
|
||||
class="ml-1"
|
||||
@click="exportMirc('clipboard')"
|
||||
@click="startExport('clipboard')"
|
||||
v-if="asciibirdMeta.length"
|
||||
>
|
||||
Export mIRC to Clipboard
|
||||
|
@ -55,12 +39,7 @@
|
|||
>
|
||||
Save Asciibird State
|
||||
</li>
|
||||
<li
|
||||
@click="startImport('asb')"
|
||||
class="ml-1"
|
||||
>
|
||||
Load Asciibird State
|
||||
</li>
|
||||
<li @click="startImport('asb')" class="ml-1">Load Asciibird State</li>
|
||||
<li
|
||||
@click="$store.commit('openModal', 'edit-ascii')"
|
||||
class="ml-1"
|
||||
|
@ -82,7 +61,7 @@
|
|||
style="display: none"
|
||||
ref="asciiInput"
|
||||
@change="onImport()"
|
||||
>
|
||||
/>
|
||||
|
||||
<template v-if="asciibirdMeta.length">
|
||||
<t-button
|
||||
|
@ -95,10 +74,7 @@
|
|||
{{ value.title }}
|
||||
</t-button>
|
||||
|
||||
<Toolbar
|
||||
:canvas-x="canvasX"
|
||||
:canvas-y="canvasY"
|
||||
/>
|
||||
<Toolbar :canvas-x="canvasX" :canvas-y="canvasY" />
|
||||
<DebugPanel
|
||||
:canvas-x="canvasX"
|
||||
:canvas-y="canvasY"
|
||||
|
@ -113,9 +89,7 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<div style="left: 35%; top: 15%; position: absolute; z-index: -2">
|
||||
<h1 style="font-size: 72px; text-align: center">
|
||||
ASCIIBIRD
|
||||
</h1>
|
||||
<h1 style="font-size: 72px; text-align: center">ASCIIBIRD</h1>
|
||||
<h1 style="font-size: 13px; text-align: center">
|
||||
Right click to start
|
||||
</h1>
|
||||
|
@ -125,64 +99,31 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import LZString from 'lz-string';
|
||||
import Toolbar from './components/Toolbar.vue';
|
||||
import DebugPanel from './components/DebugPanel.vue';
|
||||
import Editor from './views/Editor.vue';
|
||||
import LZString from "lz-string";
|
||||
import Toolbar from "./components/Toolbar.vue";
|
||||
import DebugPanel from "./components/DebugPanel.vue";
|
||||
import Editor from "./views/Editor.vue";
|
||||
|
||||
import CharPicker from './components/parts/CharPicker.vue';
|
||||
import ColourPicker from './components/parts/ColourPicker.vue';
|
||||
import ContextMenu from './components/parts/ContextMenu.vue';
|
||||
import CharPicker from "./components/parts/CharPicker.vue";
|
||||
import ColourPicker from "./components/parts/ColourPicker.vue";
|
||||
import ContextMenu from "./components/parts/ContextMenu.vue";
|
||||
|
||||
import NewAscii from './components/modals/NewAscii.vue';
|
||||
import EditAscii from './components/modals/EditAscii.vue';
|
||||
import PasteAscii from './components/modals/PasteAscii.vue';
|
||||
import NewAscii from "./components/modals/NewAscii.vue";
|
||||
import EditAscii from "./components/modals/EditAscii.vue";
|
||||
import PasteAscii from "./components/modals/PasteAscii.vue";
|
||||
|
||||
import { parseMircAscii, toolbarIcons } from './ascii';
|
||||
import {
|
||||
parseMircAscii,
|
||||
toolbarIcons,
|
||||
exportMirc,
|
||||
downloadFile,
|
||||
checkForGetRequest,
|
||||
} from "./ascii";
|
||||
|
||||
export default {
|
||||
async created() {
|
||||
// Load from irc watch if present in the URL bar
|
||||
const asciiUrlCdn = new URL(location.href).searchParams.get('ascii');
|
||||
if (asciiUrlCdn) {
|
||||
const res = await fetch(`https://ascii.jewbird.live/${asciiUrlCdn}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
},
|
||||
});
|
||||
|
||||
const asciiData = await res.text();
|
||||
this.mircAsciiImport(asciiData, asciiUrlCdn);
|
||||
}
|
||||
|
||||
const asciiUrl = new URL(location.href).searchParams.get('ircwatch');
|
||||
if (asciiUrl) {
|
||||
const res = await fetch(`https://irc.watch/ascii/txt/${asciiUrl}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
},
|
||||
});
|
||||
|
||||
const asciiData = await res.text();
|
||||
this.mircAsciiImport(asciiData, asciiUrl);
|
||||
}
|
||||
|
||||
const haxAscii = new URL(location.href).searchParams.get('haxAscii');
|
||||
if (haxAscii) {
|
||||
const res = await fetch(`https://art.h4x.life/${haxAscii}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
},
|
||||
});
|
||||
|
||||
// Considers paths
|
||||
const asciiName = haxAscii.split('/').pop();
|
||||
const asciiData = await res.text();
|
||||
this.mircAsciiImport(asciiData, asciiName);
|
||||
}
|
||||
checkForGetRequest();
|
||||
},
|
||||
components: {
|
||||
Toolbar,
|
||||
|
@ -195,7 +136,7 @@ export default {
|
|||
EditAscii,
|
||||
PasteAscii,
|
||||
},
|
||||
name: 'Dashboard',
|
||||
name: "Dashboard",
|
||||
data: () => ({
|
||||
showNewAsciiModal: false,
|
||||
currentTab: 1,
|
||||
|
@ -212,8 +153,8 @@ export default {
|
|||
},
|
||||
icon() {
|
||||
return [
|
||||
this.currentTool.fa ?? 'fas',
|
||||
this.currentTool.icon ?? 'mouse-pointer',
|
||||
this.currentTool.fa ?? "fas",
|
||||
this.currentTool.icon ?? "mouse-pointer",
|
||||
];
|
||||
},
|
||||
options() {
|
||||
|
@ -262,15 +203,15 @@ export default {
|
|||
const fileReader = new FileReader();
|
||||
|
||||
const fileType = this.importType;
|
||||
fileReader.addEventListener('load', () => {
|
||||
fileReader.addEventListener("load", () => {
|
||||
switch (fileType) {
|
||||
case 'asb':
|
||||
case "asb":
|
||||
this.importAsciibirdState(fileReader.result, filename);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'mirc':
|
||||
this.mircAsciiImport(fileReader.result, filename);
|
||||
case "mirc":
|
||||
parseMircAscii(fileReader.result, filename);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -285,21 +226,18 @@ export default {
|
|||
// console.log(this.importType);
|
||||
this.$refs.asciiInput.click();
|
||||
},
|
||||
mircAsciiImport(contents, filename) {
|
||||
parseMircAscii(contents, filename);
|
||||
},
|
||||
importAsciibirdState(fileContents) {
|
||||
const contents = JSON.parse(
|
||||
LZString.decompressFromEncodedURIComponent(fileContents),
|
||||
LZString.decompressFromEncodedURIComponent(fileContents)
|
||||
);
|
||||
this.$store.commit('changeState', { ...contents });
|
||||
this.$store.commit("changeState", { ...contents });
|
||||
},
|
||||
exportAsciibirdState() {
|
||||
let output;
|
||||
|
||||
try {
|
||||
output = LZString.compressToEncodedURIComponent(
|
||||
JSON.stringify(this.$store.getters.state),
|
||||
JSON.stringify(this.$store.getters.state)
|
||||
);
|
||||
|
||||
// Default timestamp for filename
|
||||
|
@ -311,110 +249,44 @@ export default {
|
|||
const mi = today.getMinutes();
|
||||
const s = today.getSeconds();
|
||||
|
||||
this.downloadToFile(
|
||||
downloadFile(
|
||||
output,
|
||||
`asciibird-${y}-${m}-${d}-${h}-${mi}-${s}.asb`,
|
||||
'application/gzip',
|
||||
"application/gzip"
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
exportMirc(type) {
|
||||
const { currentAscii } = this.$store.getters;
|
||||
const blocks = this.$store.getters.currentAsciiBlocks;
|
||||
const output = [];
|
||||
let curBlock = null;
|
||||
let prevBlock = { bg: -1, fg: -1 };
|
||||
|
||||
for (let y = 0; y <= blocks.length - 1; y++) {
|
||||
if (y >= currentAscii.height) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let x = 0; x <= blocks[y].length - 1; x++) {
|
||||
if (x >= currentAscii.width) {
|
||||
continue;
|
||||
}
|
||||
|
||||
curBlock = blocks[y][x];
|
||||
|
||||
// If we have a difference between our previous block
|
||||
// we'll put a colour codes and continue as normal
|
||||
if (curBlock.bg !== prevBlock.bg || curBlock.fg !== prevBlock.fg) {
|
||||
curBlock = { ...blocks[y][x] };
|
||||
const zeroPad = (num, places) => String(num).padStart(places, '0');
|
||||
output.push(
|
||||
`\u0003${zeroPad(
|
||||
curBlock.fg ?? this.options.defaultFg,
|
||||
2,
|
||||
)},${zeroPad(curBlock.bg ?? this.options.defaultBg, 2)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// null .chars will end up as space
|
||||
output.push(curBlock.char ?? ' ');
|
||||
prevBlock = blocks[y][x];
|
||||
}
|
||||
|
||||
// We can never have a -1 colour code so we'll always
|
||||
// write one at the start of each line
|
||||
prevBlock = { bg: -1, fg: -1 };
|
||||
|
||||
// New line except for the very last line
|
||||
if (y < blocks.length - 1) {
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
// Download to a txt file
|
||||
// Check if txt already exists and append it
|
||||
const filename = currentAscii.title.slice(currentAscii.title.length - 3) === 'txt'
|
||||
? currentAscii.title
|
||||
: `${currentAscii.title}.txt`;
|
||||
startExport(type) {
|
||||
let ascii = exportMirc();
|
||||
|
||||
switch (type) {
|
||||
case 'clipboard':
|
||||
this.$copyText(output.join('')).then(
|
||||
case "clipboard":
|
||||
this.$copyText(ascii.output.join("")).then(
|
||||
(e) => {
|
||||
alert('Copied');
|
||||
console.log(e);
|
||||
alert("Copied");
|
||||
},
|
||||
(e) => {
|
||||
alert('Can not copy');
|
||||
console.log(e);
|
||||
},
|
||||
alert("Can not copy");
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'file':
|
||||
this.downloadToFile(output.join(''), filename, 'text/plain');
|
||||
case "file":
|
||||
downloadFile(ascii.output.join(""), ascii.filename, "text/plain");
|
||||
break;
|
||||
}
|
||||
},
|
||||
downloadToFile(content, filename, contentType) {
|
||||
const downloadFile = (content, filename, contentType) => {
|
||||
const a = document.createElement('a');
|
||||
const file = new Blob([content], { type: contentType });
|
||||
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = filename;
|
||||
a.click();
|
||||
|
||||
URL.revokeObjectURL(a.href);
|
||||
};
|
||||
|
||||
return downloadFile(content, filename, contentType);
|
||||
},
|
||||
changeTab(key) {
|
||||
// Update the tab index in vuex store
|
||||
this.currentTab = key;
|
||||
this.$store.commit('changeTab', key);
|
||||
this.$store.commit("changeTab", key);
|
||||
},
|
||||
clearCache() {
|
||||
localStorage.clear();
|
||||
window.location.href = '/';
|
||||
window.location.href = "/";
|
||||
},
|
||||
captureMouse(event) {
|
||||
this.dashboardX = event.pageX;
|
||||
|
|
265
src/ascii.js
265
src/ascii.js
|
@ -120,6 +120,68 @@ export const mircColours99 = [
|
|||
"#ffffff",
|
||||
];
|
||||
|
||||
// Chars that end up in the toolbar
|
||||
export const charCodes = [' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
|
||||
'.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A',
|
||||
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
|
||||
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e',
|
||||
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '{', '|', '}', '~', 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è',
|
||||
'ï', 'î', 'ì', 'Ä', 'Å', 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', 'ø', '£',
|
||||
'Ø', '×', 'ƒ', 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '®', '¬', '½', '¼', '¡', '«',
|
||||
'»', '░', '▒', '▓', '│', '┤', 'Á', 'Â', 'À', '©', '╣', '║', '╗', '╝', '¢', '¥', '┐', '└',
|
||||
'┴', '┬', '├', '─', '┼', 'ã', 'Ã', '╚', '╔', '╩', '╦', '╠', '═', '╬', '¤', 'ð', 'Ð', 'Ê',
|
||||
'Ë', 'È', 'ı', 'Í', 'Î', 'Ï', '┘', '┌', '█', '▄', '¦', 'Ì', '▀', 'Ó', 'ß', 'Ô', 'Ò', 'õ',
|
||||
'Õ', 'µ', 'þ', 'Þ', 'Ú', 'Û', 'Ù', 'ý', 'Ý', '¯', '´', '≡', '±', '‗', '¾', '¶', '§', '÷',
|
||||
'¸', '°', '¨', '·', '¹', '³', '²',
|
||||
];
|
||||
|
||||
// Toolbar icons
|
||||
export const toolbarIcons = [{
|
||||
name: 'default',
|
||||
icon: 'mouse-pointer',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/mouse-pointer-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'select',
|
||||
icon: 'square',
|
||||
fa: 'far',
|
||||
svgPath: 'assets/square-regular.svg',
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
icon: 'font',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/font-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'fill',
|
||||
icon: 'fill-drip',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/fill-drip-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'brush',
|
||||
icon: 'paint-brush',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/paint-brush-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'dropper',
|
||||
icon: 'eye-dropper',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/eye-dropper-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'eraser',
|
||||
icon: 'eraser',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/eraser-solid.svg',
|
||||
},
|
||||
];
|
||||
|
||||
export const emptyBlock = {
|
||||
bg: null,
|
||||
fg: null,
|
||||
|
@ -286,11 +348,11 @@ export const parseMircAscii = (content, title) => {
|
|||
parsedColour = parseInt(`${colourChar1}${colourChar2}`);
|
||||
|
||||
if (
|
||||
!Number.isNaN(colourChar1)
|
||||
&& !Number.isNaN(colourChar2)
|
||||
&& parseInt(colourChar2) > parseInt(colourChar1)
|
||||
&& !Number.isNaN(parsedColour)
|
||||
&& parseInt(parsedColour) < 10
|
||||
!Number.isNaN(colourChar1) &&
|
||||
!Number.isNaN(colourChar2) &&
|
||||
parseInt(colourChar2) > parseInt(colourChar1) &&
|
||||
!Number.isNaN(parsedColour) &&
|
||||
parseInt(parsedColour) < 10
|
||||
) {
|
||||
parsedColour = parseInt(colourChar2);
|
||||
widthOfColCodes += 1;
|
||||
|
@ -298,8 +360,8 @@ export const parseMircAscii = (content, title) => {
|
|||
}
|
||||
|
||||
if (
|
||||
parseInt(colourChar2) === parseInt(colourChar1)
|
||||
&& parseInt(parsedColour) < 10
|
||||
parseInt(colourChar2) === parseInt(colourChar1) &&
|
||||
parseInt(parsedColour) < 10
|
||||
) {
|
||||
parsedColour = parseInt(colourChar1);
|
||||
asciiStringArray.shift();
|
||||
|
@ -357,6 +419,7 @@ export const parseMircAscii = (content, title) => {
|
|||
return true;
|
||||
};
|
||||
|
||||
// Creates new blank ASCII
|
||||
export const createNewAscii = (forms) => {
|
||||
const newAscii = {
|
||||
title: forms.createAscii.title,
|
||||
|
@ -389,66 +452,134 @@ export const createNewAscii = (forms) => {
|
|||
return true;
|
||||
};
|
||||
|
||||
// Chars that end up in the toolbar
|
||||
export const charCodes = [' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-',
|
||||
'.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A',
|
||||
'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
|
||||
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e',
|
||||
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '{', '|', '}', '~', 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è',
|
||||
'ï', 'î', 'ì', 'Ä', 'Å', 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', 'ø', '£',
|
||||
'Ø', '×', 'ƒ', 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '®', '¬', '½', '¼', '¡', '«',
|
||||
'»', '░', '▒', '▓', '│', '┤', 'Á', 'Â', 'À', '©', '╣', '║', '╗', '╝', '¢', '¥', '┐', '└',
|
||||
'┴', '┬', '├', '─', '┼', 'ã', 'Ã', '╚', '╔', '╩', '╦', '╠', '═', '╬', '¤', 'ð', 'Ð', 'Ê',
|
||||
'Ë', 'È', 'ı', 'Í', 'Î', 'Ï', '┘', '┌', '█', '▄', '¦', 'Ì', '▀', 'Ó', 'ß', 'Ô', 'Ò', 'õ',
|
||||
'Õ', 'µ', 'þ', 'Þ', 'Ú', 'Û', 'Ù', 'ý', 'Ý', '¯', '´', '≡', '±', '‗', '¾', '¶', '§', '÷',
|
||||
'¸', '°', '¨', '·', '¹', '³', '²',
|
||||
];
|
||||
// Converts ASCIIBIRD blocks to mIRC colours
|
||||
export const exportMirc = () => {
|
||||
const {
|
||||
currentAscii
|
||||
} = store.getters;
|
||||
const blocks = store.getters.currentAsciiBlocks;
|
||||
const output = [];
|
||||
let curBlock = null;
|
||||
let prevBlock = {
|
||||
bg: -1,
|
||||
fg: -1
|
||||
};
|
||||
|
||||
// Toolbar icons
|
||||
export const toolbarIcons = [{
|
||||
name: 'default',
|
||||
icon: 'mouse-pointer',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/mouse-pointer-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'select',
|
||||
icon: 'square',
|
||||
fa: 'far',
|
||||
svgPath: 'assets/square-regular.svg',
|
||||
},
|
||||
{
|
||||
name: 'text',
|
||||
icon: 'font',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/font-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'fill',
|
||||
icon: 'fill-drip',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/fill-drip-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'brush',
|
||||
icon: 'paint-brush',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/paint-brush-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'dropper',
|
||||
icon: 'eye-dropper',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/eye-dropper-solid.svg',
|
||||
},
|
||||
{
|
||||
name: 'eraser',
|
||||
icon: 'eraser',
|
||||
fa: 'fas',
|
||||
svgPath: 'assets/eraser-solid.svg',
|
||||
},
|
||||
];
|
||||
for (let y = 0; y <= blocks.length - 1; y++) {
|
||||
if (y >= currentAscii.height) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let x = 0; x <= blocks[y].length - 1; x++) {
|
||||
if (x >= currentAscii.width) {
|
||||
continue;
|
||||
}
|
||||
|
||||
curBlock = blocks[y][x];
|
||||
|
||||
// If we have a difference between our previous block
|
||||
// we'll put a colour codes and continue as normal
|
||||
if (curBlock.bg !== prevBlock.bg || curBlock.fg !== prevBlock.fg) {
|
||||
curBlock = {
|
||||
...blocks[y][x]
|
||||
};
|
||||
const zeroPad = (num, places) => String(num).padStart(places, '0');
|
||||
output.push(
|
||||
`\u0003${zeroPad(
|
||||
curBlock.fg ?? this.options.defaultFg,
|
||||
2,
|
||||
)},${zeroPad(curBlock.bg ?? this.options.defaultBg, 2)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// null .chars will end up as space
|
||||
output.push(curBlock.char ?? ' ');
|
||||
prevBlock = blocks[y][x];
|
||||
}
|
||||
|
||||
// We can never have a -1 colour code so we'll always
|
||||
// write one at the start of each line
|
||||
prevBlock = {
|
||||
bg: -1,
|
||||
fg: -1
|
||||
};
|
||||
|
||||
// New line except for the very last line
|
||||
if (y < blocks.length - 1) {
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
// Download to a txt file
|
||||
// Check if txt already exists and append it
|
||||
const filename = currentAscii.title.slice(currentAscii.title.length - 3) === 'txt' ?
|
||||
currentAscii.title :
|
||||
`${currentAscii.title}.txt`;
|
||||
|
||||
return {
|
||||
filename,
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
// Download a string to a file with a filename
|
||||
export const downloadFile = (content, filename, contentType) => {
|
||||
const a = document.createElement('a');
|
||||
const file = new Blob([content], {
|
||||
type: contentType
|
||||
});
|
||||
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = filename;
|
||||
a.click();
|
||||
|
||||
URL.revokeObjectURL(a.href);
|
||||
};
|
||||
|
||||
export const checkForGetRequest = async () => {
|
||||
const asciiUrlCdn = new URL(location.href).searchParams.get('ascii');
|
||||
if (asciiUrlCdn) {
|
||||
const res = await fetch(`https://ascii.jewbird.live/${asciiUrlCdn}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
},
|
||||
});
|
||||
|
||||
const asciiData = await res.text();
|
||||
parseMircAscii(asciiData, asciiUrlCdn);
|
||||
return;
|
||||
}
|
||||
|
||||
const asciiUrl = new URL(location.href).searchParams.get('ircwatch');
|
||||
if (asciiUrl) {
|
||||
const res = await fetch(`https://irc.watch/ascii/txt/${asciiUrl}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
},
|
||||
});
|
||||
|
||||
const asciiData = await res.text();
|
||||
parseMircAscii(asciiData, asciiUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
const haxAscii = new URL(location.href).searchParams.get('haxAscii');
|
||||
if (haxAscii) {
|
||||
const res = await fetch(`https://art.h4x.life/${haxAscii}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'text/plain',
|
||||
},
|
||||
});
|
||||
|
||||
// Considers paths
|
||||
const asciiName = haxAscii.split('/').pop();
|
||||
const asciiData = await res.text();
|
||||
parseMircAscii(asciiData, asciiName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export default createNewAscii;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
:header="currentAsciiEditingTitle"
|
||||
:click-to-close="false"
|
||||
:esc-to-close="true"
|
||||
@closed="$store.commit('closeModal', 'edit-ascii')"
|
||||
>
|
||||
Width
|
||||
<t-input
|
||||
|
@ -34,7 +35,7 @@
|
|||
<template v-slot:footer>
|
||||
<div
|
||||
class="flex justify-between"
|
||||
@click="$modal.hide('edit-ascii-modal')"
|
||||
@click="$store.commit('closeModal', 'edit-ascii')"
|
||||
>
|
||||
<t-button type="button">
|
||||
Cancel
|
||||
|
@ -77,22 +78,26 @@ export default {
|
|||
},
|
||||
},
|
||||
watch: {
|
||||
showEditAsciiModal(val, old) {
|
||||
if (val !== old) {
|
||||
this.showEditModal();
|
||||
}
|
||||
showEditAsciiModal(val) {
|
||||
if (val === true) {
|
||||
this.open();
|
||||
}
|
||||
|
||||
// this.showEditModal();
|
||||
if (val === false) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
showEditModal() {
|
||||
// this.forms.editAscii.title = `Editing ASCII ${this.currentAscii.title}`;
|
||||
updateAscii() {
|
||||
this.$store.commit('updateAscii', this.forms.editAscii);
|
||||
this.close()
|
||||
},
|
||||
open() {
|
||||
this.forms.editAscii = this.currentAscii;
|
||||
this.$modal.show('edit-ascii-modal');
|
||||
},
|
||||
updateAscii() {
|
||||
this.$store.commit('updateAscii', this.forms.editAscii);
|
||||
close() {
|
||||
this.$modal.hide('edit-ascii-modal');
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<t-modal
|
||||
name="create-ascii-modal"
|
||||
name="new-ascii-modal"
|
||||
header="Create new ASCII"
|
||||
:click-to-close="false"
|
||||
:esc-to-close="true"
|
||||
@before-closed="closeNewASCII"
|
||||
@closed="$store.commit('closeModal', 'new-ascii')"
|
||||
>
|
||||
Width
|
||||
<t-input
|
||||
|
@ -33,7 +33,7 @@
|
|||
<template v-slot:footer>
|
||||
<div
|
||||
class="flex justify-between"
|
||||
@click="$modal.hide('create-ascii-modal')"
|
||||
@click="$store.commit('closeModal', 'new-ascii')"
|
||||
>
|
||||
<t-button type="button">
|
||||
Cancel
|
||||
|
@ -70,25 +70,30 @@ export default {
|
|||
},
|
||||
},
|
||||
watch: {
|
||||
showNewAsciiModal() {
|
||||
this.createClick();
|
||||
showNewAsciiModal(val) {
|
||||
if (val === true) {
|
||||
this.open();
|
||||
}
|
||||
|
||||
if (val === false) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
createClick() {
|
||||
open() {
|
||||
this.$modal.show('new-ascii-modal');
|
||||
this.forms.createAscii.title = `New ASCII ${this.$store.getters.asciibirdMeta.length + 1}`;
|
||||
this.$modal.show('create-ascii-modal');
|
||||
},
|
||||
initiateNewAscii() {
|
||||
createNewASCII(this.forms);
|
||||
this.$modal.hide('create-ascii-modal');
|
||||
},
|
||||
closeNewASCII() {
|
||||
close() {
|
||||
this.$modal.hide('new-ascii-modal');
|
||||
this.forms.createAscii.width = 80;
|
||||
this.forms.createAscii.height = 30;
|
||||
this.forms.createAscii.title = 'New ASCII';
|
||||
},
|
||||
|
||||
initiateNewAscii() {
|
||||
createNewASCII(this.forms);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
header="Import from Clipboard"
|
||||
:click-to-close="false"
|
||||
:esc-to-close="true"
|
||||
@closed="$store.commit('closeModal', 'paste-ascii')"
|
||||
>
|
||||
Title
|
||||
<t-input
|
||||
|
@ -23,7 +24,9 @@
|
|||
<div
|
||||
class="flex justify-between"
|
||||
>
|
||||
<t-button type="button">
|
||||
<t-button
|
||||
type="button"
|
||||
@click="$store.commit('closeModal', 'paste-ascii')">
|
||||
Cancel
|
||||
</t-button>
|
||||
<t-button
|
||||
|
@ -50,29 +53,39 @@ export default {
|
|||
title: 'clipboard.txt',
|
||||
}),
|
||||
computed: {
|
||||
showPasteModal() {
|
||||
return this.$store.getters.modalState.pasteModal;
|
||||
showPasteAscii() {
|
||||
return this.$store.getters.modalState.pasteAscii;
|
||||
},
|
||||
checkPasteContent() {
|
||||
return !this.pasteContent.length;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
showPasteModal(val, old) {
|
||||
if (val !== old) {
|
||||
this.pasteModal();
|
||||
}
|
||||
showPasteAscii(val, old) {
|
||||
if (val === true) {
|
||||
this.open();
|
||||
}
|
||||
|
||||
if (val === false) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
pasteModal() {
|
||||
open() {
|
||||
this.$modal.show('paste-ascii-modal');
|
||||
// this.$store.commit('openModal', 'paste-ascii')
|
||||
},
|
||||
importPasteAscii() {
|
||||
parseMircAscii(this.pasteContent, this.title);
|
||||
close() {
|
||||
console.log("close")
|
||||
this.pasteContent = '';
|
||||
this.title = 'clipboard.txt';
|
||||
this.$modal.hide('paste-ascii-modal');
|
||||
|
||||
},
|
||||
importPasteAscii() {
|
||||
parseMircAscii(this.pasteContent, this.title);
|
||||
this.close()
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<t-input
|
||||
type="number"
|
||||
name="width"
|
||||
v-model="brushSizeWidth"
|
||||
v-model="brushSizeWidthInput"
|
||||
@change="updateBrushSize"
|
||||
min="1"
|
||||
max="10"
|
||||
|
@ -16,7 +16,7 @@
|
|||
<t-input
|
||||
type="number"
|
||||
name="height"
|
||||
v-model="brushSizeHeight"
|
||||
v-model="brushSizeHeightInput"
|
||||
@change="updateBrushSize"
|
||||
min="1"
|
||||
max="10"
|
||||
|
@ -30,7 +30,7 @@
|
|||
name="options"
|
||||
value="square"
|
||||
checked
|
||||
v-model="brushSizeType"
|
||||
v-model="brushSizeTypeInput"
|
||||
@change="updateBrushSize"
|
||||
/>
|
||||
<span class="text-sm">Square</span>
|
||||
|
@ -40,7 +40,7 @@
|
|||
<t-radio
|
||||
name="options"
|
||||
value="circle"
|
||||
v-model="brushSizeType"
|
||||
v-model="brushSizeTypeInput"
|
||||
@change="updateBrushSize"
|
||||
/>
|
||||
<span class="text-sm">Circle</span>
|
||||
|
@ -50,7 +50,7 @@
|
|||
<t-radio
|
||||
name="options"
|
||||
value="cross"
|
||||
v-model="brushSizeType"
|
||||
v-model="brushSizeTypeInput"
|
||||
@change="updateBrushSize"
|
||||
/>
|
||||
<span class="text-sm">Cross</span>
|
||||
|
@ -61,8 +61,8 @@
|
|||
ref="brushcanvas"
|
||||
id="brushcanvas"
|
||||
class="brushcanvas"
|
||||
:width="brushSizeWidthPreview + 1 * currentAscii.blockWidth"
|
||||
:height="brushSizeHeightPreview + 1 * currentAscii.blockHeight"
|
||||
:width="brushSizeWidth * currentAscii.blockWidth"
|
||||
:height="brushSizeHeight * currentAscii.blockHeight"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -75,17 +75,17 @@ export default {
|
|||
mounted() {
|
||||
this.ctx = this.$refs.brushcanvas.getContext("2d");
|
||||
this.delayRedrawCanvas();
|
||||
this.brushSizeWidth = this.brushSizeWidthPreview;
|
||||
this.brushSizeHeight = this.brushSizeHeightPreview;
|
||||
this.brushSizeType = this.brushSizeTypePreview;
|
||||
this.brushSizeWidthInput = this.brushSizeWidth;
|
||||
this.brushSizeHeightInput = this.brushSizeHeight;
|
||||
this.brushSizeTypeInput = this.brushSizeType;
|
||||
},
|
||||
data: () => ({
|
||||
ctx: null,
|
||||
redraw: true,
|
||||
blocks: [],
|
||||
brushSizeHeight: 1,
|
||||
brushSizeWidth: 1,
|
||||
brushSizeType: "square",
|
||||
brushSizeHeightInput: 1,
|
||||
brushSizeWidthInput: 1,
|
||||
brushSizeTypeInput: "square",
|
||||
}),
|
||||
computed: {
|
||||
currentAscii() {
|
||||
|
@ -112,13 +112,13 @@ export default {
|
|||
getChar() {
|
||||
return this.$store.getters.getChar;
|
||||
},
|
||||
brushSizeHeightPreview() {
|
||||
brushSizeHeight() {
|
||||
return this.$store.getters.brushSizeHeight;
|
||||
},
|
||||
brushSizeWidthPreview() {
|
||||
brushSizeWidth() {
|
||||
return this.$store.getters.brushSizeWidth;
|
||||
},
|
||||
brushSizeTypePreview() {
|
||||
brushSizeType() {
|
||||
return this.$store.getters.brushSizeType;
|
||||
},
|
||||
mircColours() {
|
||||
|
@ -131,9 +131,15 @@ export default {
|
|||
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();
|
||||
|
@ -157,19 +163,19 @@ export default {
|
|||
methods: {
|
||||
updateBrushSize() {
|
||||
this.$store.commit("updateBrushSize", {
|
||||
brushSizeHeight: this.brushSizeHeight,
|
||||
brushSizeWidth: this.brushSizeWidth,
|
||||
brushSizeType: this.brushSizeType,
|
||||
brushSizeHeight: this.brushSizeHeightInput,
|
||||
brushSizeWidth: this.brushSizeWidthInput,
|
||||
brushSizeType: this.brushSizeTypeInput,
|
||||
});
|
||||
|
||||
this.ctx.clearRect(0, 0, 1000, 1000);
|
||||
this.ctx.clearRect(0, 0, 10000, 10000);
|
||||
this.delayRedrawCanvas();
|
||||
},
|
||||
drawPreview() {
|
||||
this.ctx.clearRect(0, 0, 10000, 10000);
|
||||
|
||||
const brushHeight = this.brushSizeHeightPreview;
|
||||
const brushWidth = this.brushSizeWidthPreview;
|
||||
const brushHeight = this.brushSizeHeight;
|
||||
const brushWidth = this.brushSizeWidth;
|
||||
|
||||
this.blocks = [];
|
||||
|
||||
|
@ -199,7 +205,7 @@ export default {
|
|||
for (y = 0; y < brushHeight; y++) {
|
||||
this.blocks[y] = [];
|
||||
for (x = 0; x < brushWidth; x++) {
|
||||
switch (this.brushSizeTypePreview) {
|
||||
switch (this.brushSizeType) {
|
||||
case "cross":
|
||||
// If we are 1x1 force fill 1 block, to avoid an empty 1x1
|
||||
if (x === 0 && y === 0) {
|
||||
|
|
|
@ -15,7 +15,7 @@ export default new Vuex.Store({
|
|||
modalState: {
|
||||
newAscii: false,
|
||||
editAscii: false,
|
||||
pasteModal: false,
|
||||
pasteAscii: false,
|
||||
},
|
||||
// The various options of ASCIIBIRD will eventually
|
||||
// end up in its own modal I guess
|
||||
|
@ -177,15 +177,30 @@ export default new Vuex.Store({
|
|||
openModal(state, type) {
|
||||
switch (type) {
|
||||
case 'new-ascii':
|
||||
state.modalState.newAscii = !state.modalState.newAscii;
|
||||
state.modalState.newAscii = true;
|
||||
break;
|
||||
|
||||
case 'edit-ascii':
|
||||
state.modalState.editAscii = !state.modalState.editAscii;
|
||||
state.modalState.editAscii = true;
|
||||
break;
|
||||
|
||||
case 'paste-modal':
|
||||
state.modalState.pasteModal = !state.modalState.pasteModal;
|
||||
case 'paste-ascii':
|
||||
state.modalState.pasteAscii = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
closeModal(state, type) {
|
||||
switch (type) {
|
||||
case 'new-ascii':
|
||||
state.modalState.newAscii = false;
|
||||
break;
|
||||
|
||||
case 'edit-ascii':
|
||||
state.modalState.editAscii = false;
|
||||
break;
|
||||
|
||||
case 'paste-ascii':
|
||||
state.modalState.pasteAscii = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -214,6 +229,13 @@ export default new Vuex.Store({
|
|||
blockSizeMultiplier: (state) => state.blockSizeMultiplier,
|
||||
brushBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.brushBlocks)) || [],
|
||||
selectBlocks: (state) => JSON.parse(LZString.decompressFromUTF16(state.selectBlocks)) || [],
|
||||
isModalOpen: (state) => {
|
||||
for (const modalState in state.modalState) {
|
||||
if (state.modalState[modalState] === true)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
modules: {},
|
||||
|
|
|
@ -63,7 +63,7 @@ body {
|
|||
</style>
|
||||
|
||||
<script>
|
||||
import { emptyBlock, toolbarIcons, mircColours99 } from '../ascii';
|
||||
import { emptyBlock, toolbarIcons, mircColours99, exportMirc, downloadFile } from '../ascii';
|
||||
|
||||
export default {
|
||||
name: 'Editor',
|
||||
|
@ -80,6 +80,12 @@ export default {
|
|||
|
||||
const thisIs = this;
|
||||
this.keyListener = function (e) {
|
||||
|
||||
// Stop blocking input when modals are open
|
||||
if (this.isModalOpen) {
|
||||
return
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (this.isTextEditing) {
|
||||
|
@ -88,6 +94,7 @@ export default {
|
|||
}
|
||||
|
||||
const ctrlKey = e.ctrlKey || e.metaKey;
|
||||
const shiftKey = e.shiftKey;
|
||||
|
||||
// Ctrl Z here
|
||||
// skg - thanks for mac key suggestion, bro
|
||||
|
@ -97,12 +104,11 @@ export default {
|
|||
|
||||
// Ctrl Y here
|
||||
if (e.key === 'y' && ctrlKey) {
|
||||
// Fk it works :\
|
||||
this.redo();
|
||||
}
|
||||
|
||||
// Ctrl C - copy blocks
|
||||
if (e.key === 'c' && ctrlKey) {
|
||||
if (e.key === 'c' && ctrlKey && !shiftKey) {
|
||||
if (this.selectedBlocks.length) {
|
||||
this.$store.commit('selectBlocks', this.selectedBlocks);
|
||||
this.selectedBlocks = [];
|
||||
|
@ -117,11 +123,70 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// Show / hide debug panel
|
||||
if (e.key === 'd' && ctrlKey) {
|
||||
this.$store.commit('toggleDebugPanel', !this.debugPanelState.visible);
|
||||
}
|
||||
|
||||
// New ASCII
|
||||
// Ctrl N doesn't seem to work in chrome? https://github.com/liftoff/GateOne/issues/290
|
||||
if (e.key === 'm' && ctrlKey) {
|
||||
this.$store.commit('openModal', 'new-ascii');
|
||||
}
|
||||
|
||||
// Edit ASCII
|
||||
if (e.key === 'e' && ctrlKey) {
|
||||
this.$store.commit('openModal', 'edit-ascii');
|
||||
}
|
||||
|
||||
// Paste ASCII
|
||||
if (e.key === 'p' && ctrlKey) {
|
||||
this.$store.commit('openModal', 'paste-ascii');
|
||||
}
|
||||
|
||||
// Export to clipboard
|
||||
if (e.key === 'C' && ctrlKey && shiftKey) {
|
||||
let ascii = exportMirc();
|
||||
this.$copyText(ascii.output.join('')).then(
|
||||
(e) => {
|
||||
alert('Copied');
|
||||
},
|
||||
(e) => {
|
||||
alert('Can not copy');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Export to txt
|
||||
if (e.key === 'F' && ctrlKey && shiftKey) {
|
||||
let ascii = exportMirc();
|
||||
downloadFile(ascii.output.join(''), ascii.filename, 'text/plain');
|
||||
}
|
||||
|
||||
if (e.key === ']' && ctrlKey &&
|
||||
(this.brushSizeHeight < 10 && this.brushSizeHeight >= 1) &&
|
||||
(this.brushSizeWidth < 10 && this.brushSizeWidth >= 1)) {
|
||||
|
||||
this.$store.commit("updateBrushSize", {
|
||||
brushSizeHeight: this.brushSizeHeight + 1,
|
||||
brushSizeWidth: this.brushSizeWidth + 1,
|
||||
brushSizeType: this.brushSizeType,
|
||||
});
|
||||
}
|
||||
|
||||
if (e.key === '[' && ctrlKey &&
|
||||
(this.brushSizeHeight < 10 && this.brushSizeHeight >= 1) &&
|
||||
(this.brushSizeWidth < 10 && this.brushSizeWidth >= 1)) {
|
||||
|
||||
this.$store.commit("updateBrushSize", {
|
||||
brushSizeHeight: this.brushSizeHeight - 1,
|
||||
brushSizeWidth: this.brushSizeWidth - 1,
|
||||
brushSizeType: this.brushSizeType,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
document.addEventListener('keydown', this.keyListener.bind(this));
|
||||
}
|
||||
},
|
||||
|
@ -151,6 +216,18 @@ export default {
|
|||
selectedBlocks: [],
|
||||
}),
|
||||
computed: {
|
||||
isModalOpen() {
|
||||
return this.$store.getters.isModalOpen;
|
||||
},
|
||||
brushSizeHeight() {
|
||||
return this.$store.getters.brushSizeHeight;
|
||||
},
|
||||
brushSizeWidth() {
|
||||
return this.$store.getters.brushSizeWidth;
|
||||
},
|
||||
brushSizeType() {
|
||||
return this.$store.getters.brushSizeType;
|
||||
},
|
||||
currentAscii() {
|
||||
return this.$store.getters.currentAscii;
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue