Allow concatenating images
This commit is contained in:
@@ -17,6 +17,14 @@ function onFileChange(event: Event): void {
|
||||
}
|
||||
reader.readAsDataURL(files[0]);
|
||||
}
|
||||
|
||||
function onDragStart(event: DragEvent, idx: number): void {
|
||||
event.dataTransfer!.setData('text/plain', idx.toString());
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
images
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -24,7 +32,7 @@ function onFileChange(event: Event): void {
|
||||
<input id="file-upload" type="file" @change="onFileChange">
|
||||
<label for="file-upload" class="button">Add</label>
|
||||
<div v-for="(img, idx) in images" :key="idx" class="image-file">
|
||||
<img :src="img.src" width="64" height="64" alt="" @click="$emit('selected', img)">
|
||||
<img :src="img.src" width="64" height="64" alt="" draggable="true" @click="$emit('selected', img)" @dragstart="onDragStart($event, idx)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -4,6 +4,8 @@ import { blackAndWhite, grayScale } from '../processing/gray-scale.ts';
|
||||
import ImageCollection from './ImageCollection.vue';
|
||||
|
||||
const canvas = ref<HTMLCanvasElement | null>(null);
|
||||
const collection = ref<typeof ImageCollection>();
|
||||
const overlay = ref<string | null>(null);
|
||||
const currentWidth = ref(100);
|
||||
const currentHeight = ref(100);
|
||||
let img: HTMLImageElement;
|
||||
@@ -44,11 +46,45 @@ function onChangeSlideHeight() {
|
||||
canvas.value!.height = height;
|
||||
ctx.drawImage(img, 0, 0, canvas.value!.width, height);
|
||||
}
|
||||
|
||||
function onDragOver(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
event.dataTransfer!.dropEffect = 'copy';
|
||||
if (event.offsetX > canvas.value!.width / 2) {
|
||||
overlay.value = 'right';
|
||||
} else {
|
||||
overlay.value = 'bottom';
|
||||
}
|
||||
}
|
||||
|
||||
function onDrop(event: DragEvent) {
|
||||
event.preventDefault();
|
||||
overlay.value = null;
|
||||
const id = event.dataTransfer!.getData('text/plain');
|
||||
const img: HTMLImageElement = collection.value!.images[parseInt(id)];
|
||||
if (event.offsetX > canvas.value!.width / 2) {
|
||||
const dx = canvas.value!.width;
|
||||
const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
|
||||
canvas.value!.width += img.width;
|
||||
ctx.putImageData(imageData, 0, 0)
|
||||
ctx.drawImage(img, dx, 0);
|
||||
} else {
|
||||
const dy = canvas.value!.height;
|
||||
const imageData = ctx.getImageData(0, 0, canvas.value!.width, canvas.value!.height);
|
||||
canvas.value!.height += img.height;
|
||||
ctx.putImageData(imageData, 0, 0)
|
||||
ctx.drawImage(img, 0, dy);
|
||||
}
|
||||
}
|
||||
|
||||
function onDragLeave() {
|
||||
overlay.value = null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="editor">
|
||||
<ImageCollection @selected="onSelected" />
|
||||
<ImageCollection ref="collection" @selected="onSelected" />
|
||||
<div class="working-area">
|
||||
<div class="options">
|
||||
<button @click="blackAndWhiteApply">
|
||||
@@ -60,8 +96,9 @@ function onChangeSlideHeight() {
|
||||
</div>
|
||||
<div class="inner">
|
||||
<input v-model="currentHeight" type="range" min="1" max="200" value="100" orient="vertical" @change="onChangeSlideHeight">
|
||||
<div class="preview">
|
||||
<div class="preview" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop">
|
||||
<canvas ref="canvas"></canvas>
|
||||
<div v-if="overlay" :class="`overlay overlay-${overlay}`"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls">
|
||||
|
@@ -83,3 +83,28 @@ button:focus-visible,
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
||||
.preview {
|
||||
position: relative;
|
||||
}
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
place-items: center;
|
||||
place-content: center;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
}
|
||||
.overlay-right {
|
||||
width: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
.overlay-bottom {
|
||||
height: 50%;
|
||||
top: 50%;
|
||||
}
|
||||
|
Reference in New Issue
Block a user