2019-07-04 18:06:44 +02:00
|
|
|
<template>
|
2019-08-01 21:08:46 +02:00
|
|
|
<div class="reader" v-shortkey="{left: ['arrowleft'], right: ['arrowright']}" @shortkey="navigation">
|
|
|
|
<div class="page-container">
|
2019-09-05 23:29:14 +02:00
|
|
|
<img ref="currentImage" :style="{ width: getRealPageWidth() }" :src="info.pages[page]" @load="setScroll(); setOrientation()">
|
2019-07-04 18:06:44 +02:00
|
|
|
<!-- prefetching -->
|
|
|
|
<img style="display: none;" :src="info.pages[page-1]">
|
|
|
|
<img style="display: none;" :src="info.pages[page+1]">
|
|
|
|
</div>
|
|
|
|
<div class="sidebar" :style="{ display: showSidebar ? '' : 'none' }">
|
|
|
|
<h3>{{ info.title }}</h3>
|
|
|
|
<router-link :to="'/series/' + info.series">All Volumes</router-link>
|
2019-07-04 19:32:30 +02:00
|
|
|
<p>{{ page + 1 }}/{{ info.pages.length }}</p>
|
2019-07-04 18:06:44 +02:00
|
|
|
<p>
|
2019-09-05 23:29:14 +02:00
|
|
|
<button :disabled="originalPageWidth" v-on:click="changePageWidth(-5)">-</button>
|
2019-12-22 22:17:17 +01:00
|
|
|
<span>{{ pageWidth }}</span>
|
2019-09-05 23:29:14 +02:00
|
|
|
<button :disabled="originalPageWidth" v-on:click="changePageWidth(5)">+</button>
|
|
|
|
<br/>
|
|
|
|
<button v-on:click="originalPageWidth = !originalPageWidth">{{ originalPageWidth ? 'fixed width' : '1:1' }}</button>
|
2019-07-04 18:06:44 +02:00
|
|
|
</p>
|
2019-07-16 17:11:00 +02:00
|
|
|
<button v-on:click="changeDirection">{{ direction.toUpperCase() }}</button>
|
2019-07-04 18:06:44 +02:00
|
|
|
<button class="hide" v-on:click="showSidebar = false">Hide</button>
|
|
|
|
</div>
|
|
|
|
<div class="sidebar-enabler" :style="{ display: showSidebar ? 'none' : '' }" v-on:click="showSidebar = true"></div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import API from '@/api-client.js'
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'Reader',
|
|
|
|
data () {
|
|
|
|
return {
|
|
|
|
info: {
|
|
|
|
pages: []
|
|
|
|
},
|
|
|
|
scrollPositions: [],
|
|
|
|
pageWidth: 60,
|
2019-09-05 23:29:14 +02:00
|
|
|
originalPageWidth: false,
|
2019-07-16 17:11:00 +02:00
|
|
|
showSidebar: true,
|
2019-08-02 00:25:38 +02:00
|
|
|
direction: 'rtl',
|
|
|
|
orientation: 'vertical'
|
2019-07-04 18:06:44 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
2019-07-16 17:46:16 +02:00
|
|
|
page: {
|
|
|
|
get () {
|
|
|
|
if (this.$route.hash) {
|
|
|
|
return this.$route.hash.substr(1) - 1
|
|
|
|
} else {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
},
|
|
|
|
set (value) {
|
|
|
|
this.$router.push({ hash: '#' + (value + 1) })
|
2019-07-04 18:06:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted () {
|
|
|
|
API.getVolumeInfo(this.$route.params.id, info => (this.info = info))
|
2019-12-22 22:17:30 +01:00
|
|
|
|
|
|
|
if (localStorage.pageWidth) {
|
|
|
|
this.pageWidth = parseInt(localStorage.pageWidth)
|
|
|
|
}
|
2019-07-04 18:06:44 +02:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
setPage (page) {
|
|
|
|
// save scroll position
|
|
|
|
this.scrollPositions[this.page] = window.pageYOffset
|
|
|
|
|
|
|
|
// set page
|
|
|
|
if (page >= 0 && page < this.info.pages.length) {
|
2019-07-16 17:46:16 +02:00
|
|
|
this.page = page
|
2019-07-04 18:06:44 +02:00
|
|
|
}
|
2019-07-05 07:25:33 +02:00
|
|
|
},
|
2019-07-04 18:06:44 +02:00
|
|
|
|
2019-07-05 07:25:33 +02:00
|
|
|
setScroll () {
|
2019-07-04 18:06:44 +02:00
|
|
|
// load saved scroll posotion, if available, reset to 0 otherwise
|
|
|
|
if (this.scrollPositions[this.page]) {
|
|
|
|
window.scrollTo(0, this.scrollPositions[this.page])
|
|
|
|
} else {
|
|
|
|
window.scrollTo(0, 0)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
navigation (event) {
|
2019-07-16 17:11:00 +02:00
|
|
|
if ((event.srcKey === 'right' && this.direction === 'ltr') || (event.srcKey === 'left' && this.direction === 'rtl')) {
|
|
|
|
this.setPage(this.page + 1)
|
|
|
|
} else if ((event.srcKey === 'left' && this.direction === 'ltr') || (event.srcKey === 'right' && this.direction === 'rtl')) {
|
|
|
|
this.setPage(this.page - 1)
|
|
|
|
} else {
|
|
|
|
throw new Error('cannot nagivate: invalid parameters')
|
2019-07-04 18:06:44 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
changePageWidth (change) {
|
|
|
|
if (this.pageWidth + change > 0 && this.pageWidth + change <= 100) {
|
|
|
|
this.pageWidth += change
|
2019-12-22 22:17:30 +01:00
|
|
|
localStorage.pageWidth = this.pageWidth
|
2019-07-04 18:06:44 +02:00
|
|
|
}
|
2019-07-16 17:11:00 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
changeDirection () {
|
|
|
|
if (this.direction === 'rtl') {
|
|
|
|
this.direction = 'ltr'
|
|
|
|
} else if (this.direction === 'ltr') {
|
|
|
|
this.direction = 'rtl'
|
|
|
|
} else {
|
|
|
|
throw new Error('cannot change reading direction: invalid direction currently set')
|
|
|
|
}
|
2019-08-02 00:25:38 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
setOrientation () {
|
|
|
|
let image = this.$refs.currentImage
|
|
|
|
|
|
|
|
if (image.width < image.height) {
|
|
|
|
this.orientation = 'vertical'
|
|
|
|
} else if (image.width > image.height) {
|
2019-09-05 23:41:07 +02:00
|
|
|
this.orientation = 'horizontal'
|
2019-08-02 00:25:38 +02:00
|
|
|
} else if (image.width === image.height) {
|
|
|
|
this.orientation = 'square'
|
|
|
|
}
|
2019-09-05 23:29:14 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
getRealPageWidth () {
|
|
|
|
if (this.orientation === 'horizontal') {
|
|
|
|
return '100%'
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.originalPageWidth === true) {
|
|
|
|
return 'auto'
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.pageWidth + '%'
|
2019-07-04 18:06:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.reader {
|
2019-08-01 21:08:46 +02:00
|
|
|
display: flex;
|
2019-07-04 18:06:44 +02:00
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
2019-08-01 21:08:46 +02:00
|
|
|
.page-container {
|
|
|
|
flex-grow: 1;
|
|
|
|
}
|
|
|
|
|
2019-07-16 17:53:39 +02:00
|
|
|
img {
|
|
|
|
vertical-align: top;
|
|
|
|
}
|
|
|
|
|
2019-07-04 18:06:44 +02:00
|
|
|
.sidebar-enabler {
|
|
|
|
position: absolute;
|
|
|
|
top: 0px;
|
|
|
|
right: 0px;
|
|
|
|
height: 100%;
|
|
|
|
width: 250px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.sidebar {
|
2019-08-01 21:08:46 +02:00
|
|
|
flex: 0 0 250px;
|
2019-07-04 18:06:44 +02:00
|
|
|
background-color: #eee;
|
|
|
|
height: 100vh;
|
|
|
|
position: sticky;
|
|
|
|
top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
button.hide {
|
|
|
|
bottom: 1em;
|
|
|
|
right: 1em;
|
|
|
|
position: absolute;
|
|
|
|
}
|
|
|
|
</style>
|