feat: viewer logic changes

master
丁锐 2021-12-01 17:35:45 +08:00
parent c7e9d4c206
commit e27e783b17
4 changed files with 60 additions and 17 deletions

File diff suppressed because one or more lines are too long

View File

@ -20,7 +20,7 @@
<div class="pdf-viewer__body"> <div class="pdf-viewer__body">
<div class="loading-mask" v-if="isLoading"> <div class="loading-mask" v-if="isLoading">
<slot name="loading"> <slot name="loading">
<div class="loading-content">Loading...</div> <div class="loading-content">Loading {{dotText}}</div>
</slot> </slot>
</div> </div>
<Viewer <Viewer
@ -42,8 +42,6 @@
@rendered="handleDocumentRender" @rendered="handleDocumentRender"
/> />
</div> </div>
<iframe ref="iframe" style="display: none" />
</div> </div>
</template> </template>
@ -92,9 +90,16 @@ export default {
rotate: 0, rotate: 0,
isFullpage: false, isFullpage: false,
filename: '', filename: '',
seconds: 0,
} }
}, },
computed: { computed: {
dotText() {
const len = this.seconds % 3 + 1
const dot = '.'
return dot.repeat(len)
},
viewerStyle() { viewerStyle() {
return { return {
visibility: this.isLoading ? 'hidden' : 'visible', visibility: this.isLoading ? 'hidden' : 'visible',
@ -136,6 +141,15 @@ export default {
}, },
handleUpdateLoadingState(isLoading) { handleUpdateLoadingState(isLoading) {
this.isLoading = isLoading this.isLoading = isLoading
if (this.$slots.loading) return
this._timer && clearInterval(this._timer)
if (isLoading) {
this.seconds = 0
this._timer = setInterval(() => {
this.seconds += 1
}, 500)
}
}, },
handlePasswordRequest({ callback, retry }) { handlePasswordRequest({ callback, retry }) {
// TODO: slot dialog ? // TODO: slot dialog ?

View File

@ -8,7 +8,7 @@ export default {
}, },
render(h) { render(h) {
return h('iframe', { return h('iframe', {
on: { load: this.renderChildren }, on: { load: this.handleRenderChildren },
style: { width: '100%', height: '100%', border: 'none' }, style: { width: '100%', height: '100%', border: 'none' },
}) })
}, },
@ -21,12 +21,36 @@ export default {
getContentWindow() { getContentWindow() {
return this.$el.contentWindow return this.$el.contentWindow
}, },
appendHead() {
const metaList = [
{
'http-equiv': 'content-type',
content: 'text/html; charset=UTF-8',
},
{
name: 'referrer',
content: 'no-referrer-when-downgrade',
},
]
metaList.forEach(meta => {
const metaEl = document.createElement('META')
Object.keys(meta).forEach(k => {
metaEl[k] = meta[k]
})
this.$el.contentDocument.head.appendChild(metaEl)
})
},
appendStyle(style) { appendStyle(style) {
const cssEl = document.createElement('STYLE') const cssEl = document.createElement('STYLE')
cssEl.textContent = style cssEl.textContent = style
this.$el.contentDocument.head.appendChild(cssEl) this.$el.contentDocument.head.appendChild(cssEl)
}, },
renderChildren() { handleRenderChildren() {
this.appendHead()
// inject iframe styles // inject iframe styles
this.appendStyle(style) this.appendStyle(style)
if (this.css) { if (this.css) {

View File

@ -83,7 +83,7 @@ export default {
}, },
data() { data() {
return { return {
document: null, pdf: null,
viewerContentHeight: 0, viewerContentHeight: 0,
viewportHeight: 0, viewportHeight: 0,
viewportWidth: 0, viewportWidth: 0,
@ -213,10 +213,10 @@ export default {
}) })
}, },
startLoading() { startLoading() {
this.$emit('isLoading', true) this.$emit('update:isLoading', true)
}, },
endLoading() { endLoading() {
this.$emit('isLoading', false) this.$emit('update:isLoading', false)
}, },
handleSwitchPage(page) { handleSwitchPage(page) {
this.$emit('update:page', page) this.$emit('update:page', page)
@ -231,6 +231,11 @@ export default {
this.$emit('update:filename', filename) this.$emit('update:filename', filename)
const documentLoadingTask = PDF.getDocument(this.source) const documentLoadingTask = PDF.getDocument(this.source)
// const documentLoadingTask = PDF.getDocument({
// url: this.source,
// cMapPacked: true,
// cMapUrl: 'https://unpkg.com/browse/pdfjs-dist@2.2.228/cmaps/',
// })
documentLoadingTask.onPassword = (callback, reason) => { documentLoadingTask.onPassword = (callback, reason) => {
const retry = reason === PDF.PasswordResponses.INCORRECT_PASSWORD const retry = reason === PDF.PasswordResponses.INCORRECT_PASSWORD
this.$emit('password-requested', { this.$emit('password-requested', {
@ -238,20 +243,20 @@ export default {
retry, retry,
}) })
} }
this.document = await documentLoadingTask.promise this.pdf = await documentLoadingTask.promise
this.$emit('loaded', { this.$emit('loaded', {
total: this.document.numPages, total: this.pdf.numPages,
}) })
} catch (e) { } catch (e) {
this.document = null this.pdf = null
this.$emit('loading-failed', e) this.$emit('loading-failed', e)
} finally { } finally {
this.endLoading() this.endLoading()
} }
}, },
async render() { async render() {
if (!this.document) { if (!this.pdf) {
return return
} }
try { try {
@ -259,7 +264,7 @@ export default {
await Promise.all( await Promise.all(
this.pages.map(async (pageNum, i) => { this.pages.map(async (pageNum, i) => {
const page = await this.document.getPage(pageNum) const page = await this.pdf.getPage(pageNum)
const pageWidth = page.view[2] const pageWidth = page.view[2]
const containerWidth = this.$el.clientWidth const containerWidth = this.$el.clientWidth
const targetWidth = containerWidth * 0.9 const targetWidth = containerWidth * 0.9
@ -300,7 +305,7 @@ export default {
await this.$nextTick() await this.$nextTick()
this.viewerContentHeight = this.$refs.viewerContent.clientHeight this.viewerContentHeight = this.$refs.viewerContent.clientHeight
} catch (e) { } catch (e) {
this.document = null this.pdf = null
this.$emit('rendering-failed', e) this.$emit('rendering-failed', e)
} }
}, },