add rotate view to image viewer, mobile css fix
This commit is contained in:
parent
6e993dd095
commit
fe9fedb14e
22
frontend/src/components/buttons/RotatePreview.vue
Normal file
22
frontend/src/components/buttons/RotatePreview.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<button :title="$t('buttons.info')" :aria-label="$t('buttons.info')" class="action" @click="$emit('rotate', rotate_left)">
|
||||||
|
<i class="material-icons">{{ this.icon }}</i>
|
||||||
|
<span>{{ $t('buttons.info') }}</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'rotate-button',
|
||||||
|
props: [ 'rotate_left' ],
|
||||||
|
computed: {
|
||||||
|
icon () {
|
||||||
|
if (this.rotate_left) {
|
||||||
|
return 'rotate_left'
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'rotate_right'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -20,6 +20,7 @@ import throttle from 'lodash.throttle'
|
|||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
src: String,
|
src: String,
|
||||||
|
angle: Number,
|
||||||
moveDisabledTime: {
|
moveDisabledTime: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: () => 200
|
default: () => 200
|
||||||
@ -83,17 +84,35 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
src: function () {
|
src: function () {
|
||||||
this.setCenter()
|
this.setCenter()
|
||||||
|
},
|
||||||
|
angle: function () {
|
||||||
|
this.setCenter()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imgHeight() {
|
||||||
|
let img = this.$refs.imgex
|
||||||
|
|
||||||
|
// slow version
|
||||||
|
// return img.clientHeight * Math.cos(this.angle * Math.PI) + img.clientWidth * Math.sin(this.angle * Math.PI)
|
||||||
|
return !(this.angle % 180) ? img.clientHeight : img.clientWidth
|
||||||
|
},
|
||||||
|
imgWidth() {
|
||||||
|
let img = this.$refs.imgex
|
||||||
|
|
||||||
|
// slow version
|
||||||
|
// return img.clientWidth * Math.cos(this.angle * Math.PI) + img.clientHeight * Math.sin(this.angle * Math.PI)
|
||||||
|
return !(this.angle % 180) ? img.clientWidth : img.clientHeight
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fit() {
|
fit() {
|
||||||
let img = this.$refs.imgex
|
const wScale = window.innerWidth / this.imgWidth
|
||||||
|
const hScale = window.innerHeight / this.imgHeight
|
||||||
const wScale = window.innerWidth / img.clientWidth
|
|
||||||
const hScale = window.innerHeight / img.clientHeight
|
|
||||||
|
|
||||||
this.scale = Math.min(wScale, hScale)
|
this.scale = Math.min(wScale, hScale)
|
||||||
this.minScale = this.scale
|
this.minScale = this.scale
|
||||||
|
this.maxScale = 4 * this.scale
|
||||||
this.setZoom()
|
this.setZoom()
|
||||||
},
|
},
|
||||||
refit() {
|
refit() {
|
||||||
@ -288,7 +307,7 @@ export default {
|
|||||||
setZoom() {
|
setZoom() {
|
||||||
this.scale = this.scale < this.minScale ? this.minScale : this.scale
|
this.scale = this.scale < this.minScale ? this.minScale : this.scale
|
||||||
this.scale = this.scale > this.maxScale ? this.maxScale : this.scale
|
this.scale = this.scale > this.maxScale ? this.maxScale : this.scale
|
||||||
this.$refs.imgex.style.transform = `scale(${this.scale})`
|
this.$refs.imgex.style.transform = `scale(${this.scale}) rotate(${this.angle}deg)`
|
||||||
this.refit()
|
this.refit()
|
||||||
},
|
},
|
||||||
pxStringToNumber(style) {
|
pxStringToNumber(style) {
|
||||||
|
|||||||
@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
<div class="title">{{ this.name }}</div>
|
<div class="title">{{ this.name }}</div>
|
||||||
|
|
||||||
<preview-size-button v-if="isResizeEnabled && req.type === 'image'" @change-size="toggleSize" v-bind:size="fullSize" :disabled="loading"></preview-size-button>
|
<rotate-button v-if="isGallery" :rotate_left="true" @rotate="setRotate($event)" :disabled="loading"></rotate-button>
|
||||||
|
<rotate-button v-if="isGallery" :rotate_left="false" @rotate="setRotate($event)" :disabled="loading"></rotate-button>
|
||||||
|
<preview-size-button v-if="isResizeEnabled && isGallery" @change-size="toggleSize" v-bind:size="fullSize" :disabled="loading"></preview-size-button>
|
||||||
<button @click="openMore" id="more" :aria-label="$t('buttons.more')" :title="$t('buttons.more')" class="action">
|
<button @click="openMore" id="more" :aria-label="$t('buttons.more')" :title="$t('buttons.more')" class="action">
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</button>
|
</button>
|
||||||
@ -37,7 +39,7 @@
|
|||||||
|
|
||||||
<template v-if="!loading">
|
<template v-if="!loading">
|
||||||
<div class="preview">
|
<div class="preview">
|
||||||
<ExtendedImage v-if="isGallery" :src="raw"></ExtendedImage>
|
<ExtendedImage v-if="isGallery" :src="raw" :angle="angle"></ExtendedImage>
|
||||||
<audio v-else-if="req.type == 'audio'" :src="raw" autoplay controls></audio>
|
<audio v-else-if="req.type == 'audio'" :src="raw" autoplay controls></audio>
|
||||||
<video v-else-if="req.type == 'video'" :src="raw" autoplay controls>
|
<video v-else-if="req.type == 'video'" :src="raw" autoplay controls>
|
||||||
<track
|
<track
|
||||||
@ -66,6 +68,7 @@ import { mapState } from 'vuex'
|
|||||||
import url from '@/utils/url'
|
import url from '@/utils/url'
|
||||||
import { baseURL, resizePreview } from '@/utils/constants'
|
import { baseURL, resizePreview } from '@/utils/constants'
|
||||||
import { files as api } from '@/api'
|
import { files as api } from '@/api'
|
||||||
|
import RotateButton from "@/components/buttons/RotatePreview"
|
||||||
import PreviewSizeButton from '@/components/buttons/PreviewSize'
|
import PreviewSizeButton from '@/components/buttons/PreviewSize'
|
||||||
import InfoButton from '@/components/buttons/Info'
|
import InfoButton from '@/components/buttons/Info'
|
||||||
import DeleteButton from '@/components/buttons/Delete'
|
import DeleteButton from '@/components/buttons/Delete'
|
||||||
@ -82,6 +85,7 @@ const mediaTypes = [
|
|||||||
export default {
|
export default {
|
||||||
name: 'preview',
|
name: 'preview',
|
||||||
components: {
|
components: {
|
||||||
|
RotateButton,
|
||||||
PreviewSizeButton,
|
PreviewSizeButton,
|
||||||
InfoButton,
|
InfoButton,
|
||||||
DeleteButton,
|
DeleteButton,
|
||||||
@ -97,7 +101,8 @@ export default {
|
|||||||
name: '',
|
name: '',
|
||||||
subtitles: [],
|
subtitles: [],
|
||||||
fullSize: false,
|
fullSize: false,
|
||||||
isGallery: false
|
isGallery: false,
|
||||||
|
angle: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -130,6 +135,9 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
$route: function () {
|
$route: function () {
|
||||||
this.updatePreview()
|
this.updatePreview()
|
||||||
|
},
|
||||||
|
showMore: function () {
|
||||||
|
if (!this.showMore) this.hideGalleryBar()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -140,20 +148,38 @@ export default {
|
|||||||
this.$store.commit('setPreviewMode', true)
|
this.$store.commit('setPreviewMode', true)
|
||||||
this.listing = this.oldReq.items
|
this.listing = this.oldReq.items
|
||||||
this.$root.$on('preview-deleted', this.deleted)
|
this.$root.$on('preview-deleted', this.deleted)
|
||||||
if (this.isGallery) this.$root.$on('gallery-nav', this.nav)
|
if (this.isGallery) {
|
||||||
|
this.$root.$on('gallery-nav', this.nav)
|
||||||
|
document.querySelector('#previewer .overlay').addEventListener('mouseenter', this.showGalleryBar)
|
||||||
|
document.querySelector('#previewer .gallery-bar #dropdown').addEventListener('mouseenter', this.showGalleryBar)
|
||||||
|
}
|
||||||
this.updatePreview()
|
this.updatePreview()
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
window.removeEventListener('keydown', this.key)
|
window.removeEventListener('keydown', this.key)
|
||||||
this.$store.commit('setPreviewMode', false)
|
this.$store.commit('setPreviewMode', false)
|
||||||
this.$root.$off('preview-deleted', this.deleted)
|
this.$root.$off('preview-deleted', this.deleted)
|
||||||
if (this.isGallery) this.$root.$off('gallery-nav', this.nav)
|
if (this.isGallery) {
|
||||||
|
this.$root.$off('gallery-nav', this.nav)
|
||||||
|
document.querySelector('#previewer .overlay').removeEventListener('mouseenter', this.showGalleryBar)
|
||||||
|
document.querySelector('#previewer .gallery-bar #dropdown').removeEventListener('mouseenter', this.showGalleryBar)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
nav(e) {
|
nav(e) {
|
||||||
if (e===0 && this.hasPrevious) this.prev()
|
if (e===0 && this.hasPrevious) this.prev()
|
||||||
else if (e===1 && this.hasNext) this.next()
|
else if (e===1 && this.hasNext) this.next()
|
||||||
},
|
},
|
||||||
|
showGalleryBar() {
|
||||||
|
document.querySelector('#previewer .gallery-bar').style.opacity = 1
|
||||||
|
document.querySelector('#previewer .gallery-bar').style.zIndex = 'auto'
|
||||||
|
document.querySelector('#previewer .preview .image-ex-container').style.zIndex = -1
|
||||||
|
},
|
||||||
|
hideGalleryBar() {
|
||||||
|
document.querySelector('#previewer .gallery-bar').style.removeProperty('opacity')
|
||||||
|
document.querySelector('#previewer .gallery-bar').style.zIndex = 2
|
||||||
|
document.querySelector('#previewer .preview .image-ex-container').style.zIndex = 'auto'
|
||||||
|
},
|
||||||
deleted () {
|
deleted () {
|
||||||
this.listing = this.listing.filter(item => item.name !== this.name)
|
this.listing = this.listing.filter(item => item.name !== this.name)
|
||||||
|
|
||||||
@ -189,6 +215,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async updatePreview () {
|
async updatePreview () {
|
||||||
|
this.angle = 0
|
||||||
if (this.req.subtitles) {
|
if (this.req.subtitles) {
|
||||||
this.subtitles = this.req.subtitles.map(sub => `${baseURL}/api/raw${sub}?auth=${this.jwt}&inline=true`)
|
this.subtitles = this.req.subtitles.map(sub => `${baseURL}/api/raw${sub}?auth=${this.jwt}&inline=true`)
|
||||||
}
|
}
|
||||||
@ -243,6 +270,13 @@ export default {
|
|||||||
resetPrompts () {
|
resetPrompts () {
|
||||||
this.$store.commit('closeHovers')
|
this.$store.commit('closeHovers')
|
||||||
},
|
},
|
||||||
|
setRotate(rotate_left) {
|
||||||
|
if (rotate_left) {
|
||||||
|
this.angle -= 90
|
||||||
|
} else {
|
||||||
|
this.angle += 90
|
||||||
|
}
|
||||||
|
},
|
||||||
toggleSize () {
|
toggleSize () {
|
||||||
this.fullSize = !this.fullSize
|
this.fullSize = !this.fullSize
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user