add simple image viewer

This commit is contained in:
Salem Yaslem 2024-11-04 12:34:53 +03:00
parent 21dc8009ba
commit dac3982370
2 changed files with 80 additions and 4 deletions

13
app.vue
View File

@ -3,7 +3,7 @@ import { getElementInfo } from "moveable";
import { VueSelecto } from "vue3-selecto"; import { VueSelecto } from "vue3-selecto";
import { useDisplay } from 'vuetify/lib/framework.mjs'; import { useDisplay } from 'vuetify/lib/framework.mjs';
import { HistoryManager } from './composables/history-manager'; import { HistoryManager } from './composables/history-manager';
import { FilesManager, supportedExtensions } from './composables/files-manager'; import { FilesManager, supportedExtensions, imageExtensions } from './composables/files-manager';
import type { iFile } from "composables/worker/7zip-manager" import type { iFile } from "composables/worker/7zip-manager"
import { videoExtensions, binaryExtensions } from '#imports'; import { videoExtensions, binaryExtensions } from '#imports';
@ -73,8 +73,9 @@ watchEffect(async () => {
selectedElement.classList.remove("selected"); selectedElement.classList.remove("selected");
} }
// Experimental feature // Update to handle both video and image files
if (videoExtensions.includes(filesManager.getFile(selectedPath.value)?.extension?.toLowerCase())) { if (videoExtensions.includes(filesManager.getFile(selectedPath.value)?.extension?.toLowerCase()) ||
imageExtensions.includes(filesManager.getFile(selectedPath.value)?.extension?.toLowerCase())) {
mediaBlobUrl.value = await filesManager.getFileBlobUrl(selectedPath.value) as string; mediaBlobUrl.value = await filesManager.getFileBlobUrl(selectedPath.value) as string;
} }
}) })
@ -204,7 +205,11 @@ function stepUp(path: string) {
<MediaVideoPlayer :src="mediaBlobUrl"></MediaVideoPlayer> <MediaVideoPlayer :src="mediaBlobUrl"></MediaVideoPlayer>
</template> </template>
<template <template
v-if="!filesManager.getFile(selectedPath)?.isFolder && files.length && !videoExtensions.includes(filesManager.getFile(selectedPath)?.extension) && !binaryExtensions.includes(filesManager.getFile(selectedPath)?.extension)"> v-if="!filesManager.getFile(selectedPath)?.isFolder && imageExtensions.includes(filesManager.getFile(selectedPath)?.extension)">
<ImageViewer :src="mediaBlobUrl"></ImageViewer>
</template>
<template
v-if="!filesManager.getFile(selectedPath)?.isFolder && files.length && !imageExtensions.includes(filesManager.getFile(selectedPath)?.extension) && !videoExtensions.includes(filesManager.getFile(selectedPath)?.extension) && !binaryExtensions.includes(filesManager.getFile(selectedPath)?.extension)">
<TextEditor :file="filesManager.getFile(selectedPath)" :filesManager="filesManager"></TextEditor> <TextEditor :file="filesManager.getFile(selectedPath)" :filesManager="filesManager"></TextEditor>
</template> </template>
<template <template

View File

@ -0,0 +1,71 @@
<script setup lang="ts">
const props = defineProps<{
src: string;
}>();
const scale = ref(1);
const rotation = ref(0);
function zoomIn() {
scale.value = Math.min(scale.value + 0.1, 3);
}
function zoomOut() {
scale.value = Math.max(scale.value - 0.1, 0.1);
}
function resetZoom() {
scale.value = 1;
rotation.value = 0;
}
function rotateImage() {
rotation.value = (rotation.value + 90) % 360;
}
</script>
<template>
<div class="image-viewer">
<div class="image-controls">
<v-btn icon="mdi-plus" @click="zoomIn" title="Zoom In"></v-btn>
<v-btn icon="mdi-minus" @click="zoomOut" title="Zoom Out"></v-btn>
<v-btn icon="mdi-rotate-right" @click="rotateImage" title="Rotate"></v-btn>
<v-btn icon="mdi-refresh" @click="resetZoom" title="Reset"></v-btn>
</div>
<div class="image-container">
<img :src="src" :style="{
transform: `scale(${scale}) rotate(${rotation}deg)`,
transition: 'transform 0.2s ease-in-out'
}" />
</div>
</div>
</template>
<style scoped>
.image-viewer {
height: 100%;
display: flex;
flex-direction: column;
}
.image-controls {
padding: 8px;
display: flex;
gap: 8px;
justify-content: center;
}
.image-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-container img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
</style>