mirror of
https://github.com/xlmnxp/extractify.zip.git
synced 2024-11-23 17:13:12 +03:00
add simple image viewer
This commit is contained in:
parent
21dc8009ba
commit
dac3982370
13
app.vue
13
app.vue
@ -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
|
||||||
|
71
components/ImageViewer.vue
Normal file
71
components/ImageViewer.vue
Normal 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>
|
Loading…
Reference in New Issue
Block a user