image overlay trace
This commit is contained in:
parent
89d801c1ef
commit
5c05ad0495
|
@ -71,7 +71,7 @@ ASCIIBIRD is mostly usable. There are some bugs however to note at the moment. R
|
|||
|
||||
* Having more than a few layers depending on ascii size will slow things down, until the `fillNullBlocks` is refactored.
|
||||
* CHUNKED DIFF ENGINE
|
||||
|
||||
|
||||
* Messing with deleting layers, if you somehow have a layer that isn't selected, it'll be buggy. This is hard to do.
|
||||
|
||||
## Focusing on Now / Roadmap
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<NewAscii />
|
||||
<Options />
|
||||
<Options v-if="asciibirdMeta.length" />
|
||||
<EditAscii v-if="asciibirdMeta.length" />
|
||||
<PasteAscii />
|
||||
<ImageOverlay v-if="asciibirdMeta.length" />
|
||||
|
||||
<KeyboardShortcuts
|
||||
:selected-blocks="selectedBlocks"
|
||||
|
@ -212,6 +213,7 @@ import ContextMenu from "./components/parts/ContextMenu.vue";
|
|||
|
||||
import NewAscii from "./components/modals/NewAscii.vue";
|
||||
import Options from "./components/modals/Options.vue";
|
||||
import ImageOverlay from "./components/modals/ImageOverlay.vue";
|
||||
import EditAscii from "./components/modals/EditAscii.vue";
|
||||
import PasteAscii from "./components/modals/PasteAscii.vue";
|
||||
|
||||
|
@ -257,7 +259,8 @@ export default {
|
|||
BrushPreview,
|
||||
KeyboardShortcuts,
|
||||
LayersLibrary,
|
||||
Options
|
||||
Options,
|
||||
ImageOverlay
|
||||
},
|
||||
name: "Dashboard",
|
||||
data: () => ({
|
||||
|
|
18
src/ascii.js
18
src/ascii.js
|
@ -251,6 +251,15 @@ export const parseMircAscii = async (content, title) => {
|
|||
}],
|
||||
history: [],
|
||||
redo: [],
|
||||
imageOverlay: {
|
||||
url: null,
|
||||
opacity: 95,
|
||||
position: 'centered',
|
||||
size: 100,
|
||||
repeatx: true,
|
||||
repeaty: true,
|
||||
visible: false,
|
||||
},
|
||||
x: blockWidth * 35, // the dragable ascii canvas x
|
||||
y: blockHeight * 2, // the dragable ascii canvas y
|
||||
selectedLayer: 0,
|
||||
|
@ -451,6 +460,15 @@ export const createNewAscii = (forms) => {
|
|||
width: forms.createAscii.width,
|
||||
height: forms.createAscii.height,
|
||||
}],
|
||||
imageOverlay: {
|
||||
url: null,
|
||||
opacity: 95,
|
||||
position: 'centered',
|
||||
size: 100,
|
||||
repeatx: true,
|
||||
repeaty: true,
|
||||
visible: false,
|
||||
},
|
||||
selectedLayer: 0,
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<template>
|
||||
<t-modal
|
||||
name="overlay-modal"
|
||||
header="ASCIIBIRD Nance Trace Mode"
|
||||
:click-to-close="false"
|
||||
:esc-to-close="true"
|
||||
@closed="$store.commit('closeModal', 'overlay')"
|
||||
>
|
||||
<template v-slot:default>
|
||||
<div class="flex">
|
||||
|
||||
<span class="text-sm">URL</span>
|
||||
<t-input
|
||||
type="text"
|
||||
name="url"
|
||||
v-model="imageOverlay.url"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex">
|
||||
<label class="ml-1 w-1/3">
|
||||
<t-checkbox
|
||||
class="form-checkbox m-1"
|
||||
name="repeatx"
|
||||
v-model="imageOverlay.repeatx"
|
||||
/>
|
||||
<span class="text-sm">Repeat X</span>
|
||||
</label>
|
||||
|
||||
<label class="ml-1 w-1/3">
|
||||
<t-checkbox
|
||||
class="form-checkbox m-1"
|
||||
name="repeatx"
|
||||
v-model="imageOverlay.repeaty"
|
||||
/>
|
||||
<span class="text-sm">Repeat Y</span>
|
||||
</label>
|
||||
|
||||
<label class="ml-1 w-1/3">
|
||||
<t-checkbox
|
||||
class="form-checkbox m-1"
|
||||
name="visible"
|
||||
v-model="imageOverlay.visible"
|
||||
/>
|
||||
<span class="text-sm">Visible</span>
|
||||
</label>
|
||||
|
||||
<label class="ml-1 w-1/3">
|
||||
<span class="text-sm">Transparency</span>
|
||||
<t-input
|
||||
type="number"
|
||||
name="width"
|
||||
v-model="imageOverlay.opacity"
|
||||
min="1"
|
||||
max="100"
|
||||
class="m-1"
|
||||
/>
|
||||
|
||||
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:footer>
|
||||
<div
|
||||
class="flex justify-between"
|
||||
@click="$store.commit('closeModal', 'overlay')"
|
||||
>
|
||||
<t-button type="button" class="p-2"> Cancel </t-button>
|
||||
<t-button type="button" class="p-2">
|
||||
Ok
|
||||
</t-button>
|
||||
</div>
|
||||
</template>
|
||||
</t-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Overlay",
|
||||
created() {},
|
||||
mounted() {
|
||||
if (this.showOverlayModal) {
|
||||
this.open();
|
||||
} else {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
}),
|
||||
computed: {
|
||||
showOverlayModal() {
|
||||
return this.$store.getters.modalState.overlay;
|
||||
},
|
||||
imageOverlay() {
|
||||
return this.$store.getters.imageOverlay || {};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
showOverlayModal(val) {
|
||||
if (val === true) {
|
||||
this.open();
|
||||
}
|
||||
|
||||
if (val === false) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
imageOverlay:{
|
||||
handler: function(val, old) {
|
||||
this.$store.commit("updateImageOverlay", this.imageOverlay);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.$modal.show("overlay-modal");
|
||||
},
|
||||
close() {
|
||||
this.$modal.hide("overlay-modal");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -21,6 +21,44 @@
|
|||
<hr />
|
||||
|
||||
<div class="w-full bg-white rounded-lg shadow">
|
||||
<ul class="divide-y-2 divide-gray-100 mb-2">
|
||||
<div class="flex p-1">
|
||||
|
||||
<t-button
|
||||
type="button"
|
||||
class="rounded-xl"
|
||||
@click="updateImageOverlay"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', imageOverlay.visible ? 'eye' : 'eye-slash']"
|
||||
/> </t-button
|
||||
>
|
||||
<div class="w-full" @dblclick="showOverlayModal">
|
||||
<div class="flex text-right" >
|
||||
<div class="w-full">
|
||||
<t-card class="w-full pl-2">
|
||||
<span>{{
|
||||
imageOverlayUrl || 'Image Overlay'
|
||||
|
||||
}}</span>
|
||||
</t-card>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</ul>
|
||||
|
||||
<ul class="mt-1 mb-2">
|
||||
<li></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<ul class="divide-y-2 divide-gray-100 reverseorder">
|
||||
<li
|
||||
:class="`p-1 ${selectedLayerClass(key)}`"
|
||||
|
@ -110,6 +148,12 @@ export default {
|
|||
toolbarState() {
|
||||
return this.$tore.getters.toolbarState;
|
||||
},
|
||||
imageOverlay() {
|
||||
return this.$store.getters.imageOverlay || false;
|
||||
},
|
||||
imageOverlayUrl() {
|
||||
return this.imageOverlay.url ? this.imageOverlay.url.split("/").pop() : '';
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedLayer() {
|
||||
|
@ -198,6 +242,18 @@ export default {
|
|||
removeLayer(key) {
|
||||
this.$store.commit("removeLayer", key);
|
||||
},
|
||||
showOverlayModal() {
|
||||
console.log("Test")
|
||||
this.$store.commit('openModal', 'overlay');
|
||||
},
|
||||
// Image overlay
|
||||
updateImageOverlay() {
|
||||
let overlay = { ... this.imageOverlay }
|
||||
overlay.visible = ! overlay.visible
|
||||
this.$store.commit("updateImageOverlay", overlay);
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -27,6 +27,7 @@ export default new Vuex.Store({
|
|||
editAscii: false,
|
||||
pasteAscii: false,
|
||||
options: false,
|
||||
overlay: false,
|
||||
},
|
||||
isKeyboardDisabled: false,
|
||||
// The various options of ASCIIBIRD will eventually
|
||||
|
@ -114,6 +115,9 @@ export default new Vuex.Store({
|
|||
state.tab = payload;
|
||||
document.title = `asciibird - ${state.asciibirdMeta[payload].title}`;
|
||||
},
|
||||
updateImageOverlay(state, payload) {
|
||||
state.asciibirdMeta[state.tab].imageOverlay = payload;
|
||||
},
|
||||
changeDebugPanelState(state, payload) {
|
||||
state.debugPanelState = payload;
|
||||
},
|
||||
|
@ -486,6 +490,11 @@ export default new Vuex.Store({
|
|||
state.modalState.options = true;
|
||||
state.isKeyboardDisabled = true;
|
||||
break;
|
||||
|
||||
case 'overlay':
|
||||
state.modalState.overlay = true;
|
||||
state.isKeyboardDisabled = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
closeModal(state, type) {
|
||||
|
@ -509,6 +518,11 @@ export default new Vuex.Store({
|
|||
state.modalState.options = false;
|
||||
state.isKeyboardDisabled = false;
|
||||
break;
|
||||
|
||||
case 'overlay':
|
||||
state.modalState.overlay = false;
|
||||
state.isKeyboardDisabled = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
closeTab(state, tab) {
|
||||
|
@ -564,6 +578,7 @@ export default new Vuex.Store({
|
|||
}
|
||||
},
|
||||
selectedLayer: (state) => state.asciibirdMeta[state.tab].selectedLayer,
|
||||
imageOverlay: (state) => state.asciibirdMeta[state.tab].imageOverlay,
|
||||
asciibirdMeta: (state) => state.asciibirdMeta,
|
||||
nextTabValue: (state) => state.asciibirdMeta.length,
|
||||
brushSizeHeight: (state) => state.toolbarState.brushSizeHeight,
|
||||
|
|
|
@ -15,11 +15,15 @@
|
|||
@dragstop="onCavasDragStop"
|
||||
:x="currentAscii.x"
|
||||
:y="currentAscii.y"
|
||||
|
||||
>
|
||||
<canvas id="overlay-image" :style="imageOverlayStyle" :width="currentAsciiWidth * blockWidth" :height="currentAsciiHeight * blockHeight"></canvas>
|
||||
|
||||
<canvas
|
||||
ref="canvas"
|
||||
id="canvas"
|
||||
class="canvas"
|
||||
:style="canvasTransparent"
|
||||
:width="currentAsciiWidth * blockWidth"
|
||||
:height="currentAsciiHeight * blockHeight"
|
||||
/>
|
||||
|
@ -37,6 +41,8 @@
|
|||
@touchend="canvasMouseDown"
|
||||
@touchstart="canvasMouseUp"
|
||||
/>
|
||||
|
||||
|
||||
</vue-draggable-resizable>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -54,7 +60,6 @@ import {
|
|||
getBlocksWidth,
|
||||
checkVisible,
|
||||
mergeLayers,
|
||||
cyrb53,
|
||||
} from "../ascii";
|
||||
|
||||
export default {
|
||||
|
@ -238,6 +243,15 @@ export default {
|
|||
currentAsciiHeight() {
|
||||
return this.currentSelectedLayer.height;
|
||||
},
|
||||
imageOverlay() {
|
||||
return this.$store.getters.imageOverlay;
|
||||
},
|
||||
imageOverlayStyle() {
|
||||
return this.imageOverlay.visible ? `background-image: url('${this.imageOverlay.url}'); background-position: center; background-size: 100%; opacity: ${this.imageOverlay.opacity/100}; z-index: -1; position: absolute;` : 'position: absolute;'
|
||||
},
|
||||
canvasTransparent() {
|
||||
return this.imageOverlay.visible ? 'opacity: 0.6;' : 'opacity: 1;'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentAscii(val, old) {
|
||||
|
@ -500,7 +514,6 @@ export default {
|
|||
|
||||
this.$refs.canvasdrag.width = width;
|
||||
this.$refs.canvasdrag.height = height;
|
||||
|
||||
},
|
||||
onCavasDragStop(x, y) {
|
||||
// Update left and top in panel
|
||||
|
|
|
@ -5,5 +5,5 @@ module.exports = {
|
|||
extract: false
|
||||
},
|
||||
|
||||
publicPath: ''
|
||||
publicPath: '/~jewbird/'
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue