Skip to content

Commit

Permalink
Implement zoom and rotate for preview app (#7977)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan authored Nov 28, 2022
1 parent 31327c5 commit 1d5de4a
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Enhancement: Introduce zoom and rotate to the preview app

https://github.com/owncloud/web/pull/7977
https://github.com/owncloud/web/issues/7160
121 changes: 118 additions & 3 deletions packages/web-app-preview/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
:src="activeMediaFileCached.url"
:alt="activeMediaFileCached.name"
:data-id="activeMediaFileCached.id"
:style="`zoom: ${currentImageZoom};transform: rotate(${currentImageRotation}deg)`"
/>
<video
v-else-if="activeMediaFileCached.isVideo"
Expand All @@ -68,10 +69,11 @@
class="oc-background-brand oc-p-s oc-width-large oc-flex oc-flex-middle oc-flex-center oc-flex-around preview-controls-action-bar"
>
<oc-button
v-oc-tooltip="previousDescription"
class="preview-controls-previous"
appearance="raw"
variation="inverse"
:aria-label="$gettext('Show previous media file in folder')"
:aria-label="previousDescription"
@click="prev"
>
<oc-icon size="large" name="arrow-drop-left" />
Expand All @@ -81,14 +83,71 @@
<span class="oc-invisible-sr" v-text="screenreaderFileCount" />
</p>
<oc-button
v-oc-tooltip="nextDescription"
class="preview-controls-next"
appearance="raw"
variation="inverse"
:aria-label="$gettext('Show next media file in folder')"
:aria-label="nextDescription"
@click="next"
>
<oc-icon size="large" name="arrow-drop-right" />
</oc-button>
<div v-if="activeMediaFileCached.isImage" class="oc-flex oc-flex-middle">
<div class="oc-flex">
<oc-button
v-oc-tooltip="imageShrinkDescription"
class="preview-controls-image-shrink"
appearance="raw"
variation="inverse"
:aria-label="imageShrinkDescription"
@click="imageShrink"
>
<oc-icon fill-type="line" name="checkbox-indeterminate" />
</oc-button>
<oc-button
v-oc-tooltip="imageOriginalSizeDescription"
class="preview-controls-image-original-size oc-ml-s oc-mr-s"
appearance="raw"
variation="inverse"
:aria-label="imageOriginalSizeDescription"
@click="currentImageZoom = 1"
>
<span v-text="currentZoomDisplayValue" />
</oc-button>
<oc-button
v-oc-tooltip="imageZoomDescription"
class="preview-controls-image-zoom"
appearance="raw"
variation="inverse"
:aria-label="imageZoomDescription"
@click="imageZoom"
>
<oc-icon fill-type="line" name="add-box" />
</oc-button>
</div>
<div class="oc-ml-m">
<oc-button
v-oc-tooltip="imageRotateLeftDescription"
class="preview-controls-rotate-left"
appearance="raw"
variation="inverse"
:aria-label="imageRotateLeftDescription"
@click="imageRotateLeft"
>
<oc-icon fill-type="line" name="anticlockwise" />
</oc-button>
<oc-button
v-oc-tooltip="imageRotateRightDescription"
class="preview-rotate-right"
appearance="raw"
variation="inverse"
:aria-label="imageRotateRightDescription"
@click="imageRotateRight"
>
<oc-icon fill-type="line" name="clockwise" />
</oc-button>
</div>
</div>
</div>
</div>
</main>
Expand Down Expand Up @@ -133,7 +192,10 @@ export default defineComponent({
activeIndex: null,
direction: 'rtl',
cachedFiles: []
cachedFiles: [],
currentImageZoom: 1,
currentImageRotation: 0
}
},
Expand Down Expand Up @@ -201,6 +263,30 @@ export default defineComponent({
isActiveFileTypeVideo() {
return this.activeFilteredFile.mimeType.toLowerCase().startsWith('video')
},
imageShrinkDescription() {
return this.$gettext('Shrink the image')
},
imageZoomDescription() {
return this.$gettext('Enlarge the image')
},
imageOriginalSizeDescription() {
return this.$gettext('Show the image at its normal size')
},
imageRotateLeftDescription() {
return this.$gettext('Rotate the image 90 degrees to the left')
},
imageRotateRightDescription() {
return this.$gettext('Rotate the image 90 degrees to the right')
},
previousDescription() {
return this.$gettext('Show previous media file in folder')
},
nextDescription() {
return this.$gettext('Show next media file in folder')
},
currentZoomDisplayValue() {
return `${(this.currentImageZoom * 100).toFixed(0)}%`
}
},
Expand All @@ -209,6 +295,9 @@ export default defineComponent({
if (o !== n) {
this.loadMedium()
}
this.currentImageZoom = 1
this.currentImageRotation = 0
}
},
Expand Down Expand Up @@ -350,13 +439,35 @@ export default defineComponent({
}
this.activeIndex--
this.updateLocalHistory()
},
calculateZoom(zoom, factor) {
return Math.round(zoom * factor * 20) / 20
},
imageShrink() {
this.currentImageZoom = Math.max(0.1, this.calculateZoom(this.currentImageZoom, 0.8))
},
imageZoom() {
const maxZoomValue = this.calculateZoom(9, 1.25)
this.currentImageZoom = Math.min(
this.calculateZoom(this.currentImageZoom, 1.25),
maxZoomValue
)
},
imageRotateLeft() {
this.currentImageRotation =
this.currentImageRotation === -270 ? 0 : this.currentImageRotation - 90
},
imageRotateRight() {
this.currentImageRotation =
this.currentImageRotation === 270 ? 0 : this.currentImageRotation + 90
}
}
})
</script>

<style lang="scss" scoped>
.preview-player {
overflow: auto;
max-width: 90vw;
height: 70vh;
margin: 10px auto;
Expand All @@ -378,6 +489,10 @@ export default defineComponent({
color: var(--oc-color-swatch-inverse-default);
}
.preview-controls-image-original-size {
width: 42px;
}
@media (max-width: 959px) {
.preview-player {
max-width: 100vw;
Expand Down

0 comments on commit 1d5de4a

Please sign in to comment.