style clean, layers context menu
This commit is contained in:
parent
124375bc6c
commit
d09c0386b2
17
src/ascii.js
17
src/ascii.js
|
@ -765,23 +765,26 @@ export const mergeLayers = function (blocks = null) {
|
|||
store.getters.currentAsciiLayers[z].data[y] &&
|
||||
store.getters.currentAsciiLayers[z].data[y][x]
|
||||
) {
|
||||
if (curBlock.bg === undefined) {
|
||||
curBlock.bg = store.getters.currentAsciiLayers[z].data[y][x].bg;
|
||||
}
|
||||
|
||||
if (curBlock.fg === undefined) {
|
||||
curBlock.fg = store.getters.currentAsciiLayers[z].data[y][x].fg;
|
||||
} else {
|
||||
curBlock.fg = 0;
|
||||
}
|
||||
|
||||
if (curBlock.char === undefined) {
|
||||
curBlock.char = store.getters.currentAsciiLayers[z].data[y][x].char;
|
||||
}
|
||||
|
||||
if (curBlock.fg === undefined) {
|
||||
curBlock.fg = store.getters.currentAsciiLayers[z].data[y][x].fg;
|
||||
}
|
||||
|
||||
if (curBlock.bg === undefined) {
|
||||
curBlock.bg = store.getters.currentAsciiLayers[z].data[y][x].bg;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
// break;
|
||||
}
|
||||
|
||||
mergedLayers[y][x] = {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
|
||||
|
||||
<div class="flex">
|
||||
<t-button
|
||||
type="button"
|
||||
|
@ -48,13 +50,41 @@
|
|||
<li></li>
|
||||
</ul>
|
||||
|
||||
<ul class="divide-y-2 divide-gray-100 reverseorder">
|
||||
<context-menu ref="layers-menu" class="z-50" @contextmenu.prevent>
|
||||
<ul>
|
||||
<li @click="addLayer()" class="ab-context-menu-item">
|
||||
Add New Layer
|
||||
</li>
|
||||
<li @click="removeLayer(selectedLayer)" class="ab-context-menu-item">
|
||||
Remove Selected Layer
|
||||
</li>
|
||||
<li @click="downLayer(selectedLayer)" class="ab-context-menu-item">
|
||||
Move Selected Layer Up
|
||||
</li>
|
||||
<li @click="upLayer(selectedLayer)" class="ab-context-menu-item">
|
||||
Move Selected Layer Down
|
||||
</li>
|
||||
<li @click="toggleLayer(selectedLayer)" class="ab-context-menu-item">
|
||||
Show/Hide Layer
|
||||
</li>
|
||||
<li @click="showLayerRename(selectedLayer, currentLayer.label)" class="ab-context-menu-item">
|
||||
Rename Layer
|
||||
</li>
|
||||
<li @click="mergeLayers()" class="ab-context-menu-item">
|
||||
Merge All Layers
|
||||
</li>
|
||||
</ul>
|
||||
</context-menu>
|
||||
|
||||
<ul class="divide-y-2 divide-gray-100 reverseorder" @mouseup.right="openContextMenu" @contextmenu.prevent>
|
||||
<li
|
||||
:class="`p-1 ${selectedLayerClass(key)}`"
|
||||
v-for="(layer, key) in currentAsciiLayers"
|
||||
:key="key"
|
||||
@click.right="changeLayer(key)"
|
||||
@click="changeLayer(key)"
|
||||
>
|
||||
<div class="flex">
|
||||
<div class="flex" @mouseup.right="openContextMenu" @contextmenu.prevent>
|
||||
<div class="w-12">
|
||||
<t-button
|
||||
type="button"
|
||||
|
@ -77,8 +107,8 @@
|
|||
</t-button>
|
||||
</div>
|
||||
|
||||
<div class="w-full" @click="changeLayer(key)">
|
||||
<div class="flex text-right">
|
||||
<div class="w-full" >
|
||||
<div class="flex text-right" >
|
||||
<div class="w-full">
|
||||
<t-card class="w-full hover:bg-gray-300 cursor-pointer">
|
||||
<span @dblclick="showLayerRename(key, layer.label)">{{
|
||||
|
@ -118,8 +148,13 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
import ContextMenu from "./ContextMenu.vue";
|
||||
|
||||
export default {
|
||||
name: "Layers",
|
||||
components: {
|
||||
ContextMenu
|
||||
},
|
||||
created() {},
|
||||
data: () => ({}),
|
||||
computed: {
|
||||
|
@ -129,6 +164,9 @@ export default {
|
|||
selectedLayer() {
|
||||
return this.$store.getters.selectedLayer;
|
||||
},
|
||||
currentLayer() {
|
||||
return this.currentAsciiLayers[this.selectedLayer];
|
||||
},
|
||||
canToggleLayer() {
|
||||
return this.currentAsciiLayers.length > 1;
|
||||
// We want to avoid hiding all the layers, so if there's only one
|
||||
|
@ -152,6 +190,14 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
openContextMenu(e) {
|
||||
e.preventDefault();
|
||||
// These are the correct X and Y when inside the floating panel
|
||||
this.$refs["layers-menu"].open({
|
||||
pageX: e.layerX,
|
||||
pageY: e.layerY,
|
||||
});
|
||||
},
|
||||
selectBestLayer() {
|
||||
let found = false;
|
||||
this.currentAsciiLayers.map((item) => {
|
||||
|
@ -205,42 +251,51 @@ export default {
|
|||
|
||||
this.$store.commit("toggleDisableKeyboard", false);
|
||||
});
|
||||
|
||||
this.closeMenu()
|
||||
},
|
||||
updateLayerName(key, label) {
|
||||
this.$store.commit("updateLayerName", {
|
||||
key: key,
|
||||
label: label,
|
||||
});
|
||||
this.closeMenu()
|
||||
},
|
||||
addLayer() {
|
||||
this.$store.commit("addLayer");
|
||||
this.$toasted.show(`Added a new layer.`, {
|
||||
type: "success",
|
||||
});
|
||||
this.closeMenu()
|
||||
},
|
||||
mergeLayers() {
|
||||
this.$store.commit("mergeAllLayers");
|
||||
this.$toasted.show(`All layers have been merged.`, {
|
||||
type: "success",
|
||||
});
|
||||
this.closeMenu()
|
||||
},
|
||||
changeLayer(key) {
|
||||
this.$store.commit("changeLayer", key);
|
||||
},
|
||||
toggleLayer(key) {
|
||||
this.$store.commit("toggleLayer", key);
|
||||
this.closeMenu()
|
||||
},
|
||||
upLayer(key) {
|
||||
this.$store.commit("upLayer", key);
|
||||
this.closeMenu()
|
||||
},
|
||||
downLayer(key) {
|
||||
this.$store.commit("downLayer", key);
|
||||
this.closeMenu()
|
||||
},
|
||||
removeLayer(key) {
|
||||
this.$store.commit("removeLayer", key);
|
||||
this.$toasted.show(`Removed layer.`, {
|
||||
type: "success",
|
||||
});
|
||||
this.closeMenu()
|
||||
},
|
||||
showOverlayModal() {
|
||||
this.$store.commit("openModal", "overlay");
|
||||
|
@ -251,6 +306,9 @@ export default {
|
|||
overlay.visible = !overlay.visible;
|
||||
this.$store.commit("updateImageOverlay", overlay);
|
||||
},
|
||||
closeMenu() {
|
||||
this.$refs["layers-menu"].close();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -69,9 +69,9 @@ body {
|
|||
|
||||
:root {
|
||||
--bar-font-color: rgba(0, 0, 0, 0.75);
|
||||
--bar-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
--bar-font-family: Roboto, Helvetica, Arial, sans-serif;
|
||||
--bar-font-size: 15.5px;
|
||||
--bar-button-icon-size: 20px;
|
||||
--bar-button-icon-size: 18.5px;
|
||||
--bar-button-padding: 4px 7px 5px 7px;
|
||||
--bar-button-radius: 0;
|
||||
--bar-button-hover-bkg: none;
|
||||
|
@ -81,7 +81,6 @@ body {
|
|||
--bar-button-open-bkg: rgba(55, 65, 81);
|
||||
--bar-menu-bkg: rgba(255, 255, 255, 0.95);
|
||||
--bar-menu-backdrop-filter: saturate(180%) blur(20px);
|
||||
--bar-menu-backdrop-filter-bkg: rgba(255, 255, 255, 0.3);
|
||||
--bar-menu-border: solid 1px #BBB;
|
||||
--bar-menu-border-radius: 0 0 6px 6px;
|
||||
--bar-menu-item-chevron-margin: 0;
|
||||
|
|
|
@ -10,10 +10,16 @@
|
|||
<li @click="canvasToPng()" class="ml-1 text-sm hover:bg-gray-400">
|
||||
Save as PNG
|
||||
</li>
|
||||
<li @click="startExport('clipboard')" class="ml-1 text-sm hover:bg-gray-400">
|
||||
<li
|
||||
@click="startExport('clipboard')"
|
||||
class="ml-1 text-sm hover:bg-gray-400"
|
||||
>
|
||||
Export ASCII to mIRC Clipboard
|
||||
</li>
|
||||
<li @click="startExport('file')" class="ml-1 text-sm hover:bg-gray-400">
|
||||
<li
|
||||
@click="startExport('file')"
|
||||
class="ml-1 text-sm hover:bg-gray-400"
|
||||
>
|
||||
Export ASCII to mIRC File
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -28,7 +34,9 @@
|
|||
@resizestop="onCanvasResize"
|
||||
@dragstop="onCavasDragStop"
|
||||
:x="currentAscii.x"
|
||||
:handles="['bm', 'br', 'mr']"
|
||||
:y="currentAscii.y"
|
||||
style="z-index: -1;"
|
||||
>
|
||||
<canvas
|
||||
id="overlay-image"
|
||||
|
@ -82,7 +90,7 @@ import {
|
|||
canvasToPng,
|
||||
exportMirc,
|
||||
downloadFile,
|
||||
cyrb53
|
||||
cyrb53,
|
||||
} from "../ascii";
|
||||
|
||||
export default {
|
||||
|
@ -421,7 +429,7 @@ export default {
|
|||
this.dispatchBlocks(true);
|
||||
this.canTool = false;
|
||||
this.delayRedrawCanvas();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
gridView(val, old) {
|
||||
|
@ -472,8 +480,7 @@ export default {
|
|||
}
|
||||
},
|
||||
updateascii(val, old) {
|
||||
if ( (val.width !== old.width) || (val.height !== old.height) ) {
|
||||
|
||||
if (val.width !== old.width || val.height !== old.height) {
|
||||
let layers = fillNullBlocks(val.height, val.width);
|
||||
|
||||
this.canvas.width = val.width * blockWidth;
|
||||
|
@ -491,7 +498,6 @@ export default {
|
|||
this.clearToolCanvas();
|
||||
this.delayRedrawCanvas();
|
||||
}
|
||||
|
||||
},
|
||||
// Layers undo
|
||||
// currentAsciiLayers(val, old) {
|
||||
|
@ -899,37 +905,57 @@ export default {
|
|||
if (
|
||||
this.diffBlocks.new.length &&
|
||||
!this.canTool &&
|
||||
!this.isTextEditing
|
||||
!this.isTextEditing
|
||||
) {
|
||||
// If we have a difference stored, just render the difference only instead
|
||||
// of the entire ascii again
|
||||
|
||||
for (let i in this.diffBlocks.new) {
|
||||
// We also have to take into account layers, if there is a block on top
|
||||
// we will not do anything
|
||||
outer: for (let i in this.diffBlocks.new) {
|
||||
let entry = this.diffBlocks.new[i];
|
||||
canvasX = blockWidth * entry.x;
|
||||
canvasY = blockHeight * entry.y;
|
||||
curBlock = { ...entry.b };
|
||||
|
||||
if (curBlock.bg !== undefined && curBlock.bg !== null) {
|
||||
for (let j = this.currentAsciiLayers.length-1; j >= this.diffBlocks.l; j--) {
|
||||
let layer = this.currentAsciiLayers[j];
|
||||
if (layer.data[entry.y][entry.x] && j !== this.diffBlocks.l) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
// Start to draw the actual block on the canvas
|
||||
if (curBlock.bg !== undefined && curBlock.bg !== null && this.canBg) {
|
||||
this.ctx.fillStyle = this.mircColours[curBlock.bg];
|
||||
this.ctx.fillRect(canvasX, canvasY, blockWidth, blockHeight);
|
||||
}
|
||||
|
||||
if (curBlock.char !== undefined && curBlock.char !== null) {
|
||||
if (curBlock.fg !== undefined && curBlock.fg !== null) {
|
||||
if (curBlock.fg !== undefined && curBlock.fg !== null && this.canFg) {
|
||||
this.ctx.fillStyle = this.mircColours[curBlock.fg];
|
||||
} else {
|
||||
this.ctx.fillStyle = "#FFFFFF";
|
||||
this.ctx.fillStyle = this.mircColours[0];
|
||||
}
|
||||
|
||||
this.ctx.fillText(
|
||||
curBlock.char,
|
||||
canvasX,
|
||||
canvasY + blockHeight - 3
|
||||
);
|
||||
// Draw character
|
||||
if (this.canText) {
|
||||
this.ctx.fillText(
|
||||
curBlock.char,
|
||||
canvasX,
|
||||
canvasY + blockHeight - 3
|
||||
);
|
||||
} else {
|
||||
this.ctx.fillText(
|
||||
this.currentAsciiLayerBlocks[entry.y][entry.x].char || " ",
|
||||
canvasX,
|
||||
canvasY + blockHeight - 3
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset diff blocks now that they have been drawn
|
||||
this.diffBlocks = {
|
||||
l: this.selectedLayerIndex,
|
||||
new: [],
|
||||
|
@ -948,7 +974,7 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
this.canvasHash = tempHash
|
||||
this.canvasHash = tempHash;
|
||||
this.ctx.save();
|
||||
this.canvasRef.width = this.canvasRef.width;
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
@ -1045,7 +1071,6 @@ export default {
|
|||
old: [],
|
||||
};
|
||||
}
|
||||
|
||||
},
|
||||
// Mouse Up, Down and Move
|
||||
canvasMouseUp() {
|
||||
|
@ -1674,7 +1699,10 @@ export default {
|
|||
}
|
||||
|
||||
for (let x = 0; x < xLength; x++) {
|
||||
if (!this.brushBlocks[y][x] || JSON.stringify(this.brushBlocks[y][x]) === '{}') {
|
||||
if (
|
||||
!this.brushBlocks[y][x] ||
|
||||
JSON.stringify(this.brushBlocks[y][x]) === "{}"
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1870,15 +1898,15 @@ export default {
|
|||
const newColor = {
|
||||
fg: this.currentFg,
|
||||
bg: this.currentBg,
|
||||
char: this.currentChar
|
||||
char: this.currentChar,
|
||||
};
|
||||
|
||||
const current = { ... this.asciiBlockAtXy };
|
||||
const current = { ...this.asciiBlockAtXy };
|
||||
|
||||
if (!this.canBg) {
|
||||
delete newColor['bg'];
|
||||
delete newColor["bg"];
|
||||
}
|
||||
|
||||
|
||||
// If the newColor is same as the existing
|
||||
// Then return the original image.
|
||||
if (JSON.stringify(current) === JSON.stringify(newColor) && !eraser) {
|
||||
|
@ -1902,7 +1930,10 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
if (currentLayerBlocks[y] === undefined || currentLayerBlocks[y][x] === undefined) {
|
||||
if (
|
||||
currentLayerBlocks[y] === undefined ||
|
||||
currentLayerBlocks[y][x] === undefined
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1913,7 +1944,7 @@ export default {
|
|||
}
|
||||
|
||||
// We can eraser or fill
|
||||
let oldBlock = { ... targetBlock };
|
||||
let oldBlock = { ...targetBlock };
|
||||
if (!eraser) {
|
||||
if (this.canBg) {
|
||||
targetBlock.bg = this.currentBg;
|
||||
|
@ -1939,7 +1970,7 @@ export default {
|
|||
if (this.canText) {
|
||||
delete targetBlock["char"];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.storeDiffBlocks(x, y, oldBlock, targetBlock);
|
||||
|
||||
|
|
Loading…
Reference in New Issue