Implement image selector
continuous-integration/drone/push Build is passing Details

main
Clément FRÉVILLE 1 year ago
parent a6e08ba9a1
commit 29e9dffeda

@ -0,0 +1,42 @@
<script setup lang="ts">
import { ref } from "vue";
defineEmits<{
selected: [image: HTMLImageElement]
}>()
const images = ref<HTMLImageElement[]>([]);
function onFileChange(event: Event): void {
const files = (event.target as HTMLInputElement).files!;
const reader = new FileReader();
reader.onload = function(event) {
const image = new Image();
image.onload = () => images.value.push(image);
image.src = event.target!.result as string;
}
reader.readAsDataURL(files[0]);
}
</script>
<template>
<div class="file-column">
<input id="file-upload" type="file" @change="onFileChange">
<label for="file-upload"><a class="button" style="display: block">Add</a></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)">
</div>
</div>
</template>
<style>
#file-upload {
display: none;
}
.file-column {
display: flex;
flex-direction: column;
padding: 8px;
border-right: 1px solid black;
}
</style>

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { grayScale } from "../processing/gray-scale.ts"; import { grayScale } from "../processing/gray-scale.ts";
import ImageCollection from "./ImageCollection.vue";
const canvas = ref<HTMLCanvasElement | null>(null) const canvas = ref<HTMLCanvasElement | null>(null)
let ctx: CanvasRenderingContext2D; let ctx: CanvasRenderingContext2D;
@ -8,25 +9,28 @@ onMounted(() => {
ctx = canvas.value!.getContext('2d')!; ctx = canvas.value!.getContext('2d')!;
}) })
function onFileChange(event: Event) { function onSelected(img: HTMLImageElement): void {
const files = (event.target as HTMLInputElement).files!; ctx.drawImage(img, 0, 0);
const reader = new FileReader(); const imageData = ctx.getImageData(0, 0, img.width, img.height);
reader.onload = function(event) { const pixels = imageData.data;
const img = new Image(); grayScale(pixels);
img.onload = () => { ctx.putImageData(imageData, 0, 0);
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, img.width, img.height);
const pixels = imageData.data;
grayScale(pixels);
ctx.putImageData(imageData, 0, 0);
}
img.src = event.target!.result as string;
}
reader.readAsDataURL(files[0]);
} }
</script> </script>
<template> <template>
<input type="file" @change="onFileChange"> <div class="editor">
<canvas ref="canvas" width="500" height="500"></canvas> <ImageCollection @selected="onSelected" />
<canvas ref="canvas" width="500" height="500"></canvas>
</div>
</template> </template>
<style>
.editor {
display: flex;
box-shadow: 0 0 2px 2px #1a1a1a;
}
canvas {
flex-grow: 1;
}
</style>

@ -35,22 +35,27 @@ h1 {
line-height: 1.1; line-height: 1.1;
} }
button { button, .button {
border-radius: 8px; border-radius: 8px;
border: 1px solid transparent; border: 1px solid transparent;
padding: 0.6em 1.2em; padding: 0.6em 1.2em;
margin-bottom: 8px;
font-size: 1em; font-size: 1em;
font-weight: 500; font-weight: 500;
font-family: inherit; font-family: inherit;
background-color: #1a1a1a; background-color: #1a1a1a;
cursor: pointer; cursor: pointer;
transition: border-color 0.25s; transition: border-color 0.25s;
color: inherit;
text-decoration: none;
} }
button:hover { button:hover, .button:hover {
border-color: #646cff; border-color: #646cff;
} }
button:focus, button:focus,
button:focus-visible { button:focus-visible,
.button:focus,
.button:focus-visible {
outline: 4px auto -webkit-focus-ring-color; outline: 4px auto -webkit-focus-ring-color;
} }

Loading…
Cancel
Save