Open Mik-A opened 6 years ago
I'm also looking for information on how to get the text selection layer working. Any advice?
Same. Also trying to do text selection on the pdf file being generated. Any update?
Same request. Also want text selection. Thanks
Same request. Also want text selection. Thanks
I followed this guide:
https://usefulangle.com/post/90/javascript-pdfjs-enable-text-layer
I had to make adjustment, because i don't use the pdf scale, but just manipulated width of the surrounding div and i use v-dragscroll to allow moving in a zoomed pdf.
<template>
<!-- ... some buttons to zoom, switch pages, rotate etc. and activate textSelectionEnabled ... !-->
<!-- wrapper div with position relative outside, using v-dragscroll to use mouse/touch device to move inside doc -->
<div
v-dragscroll='!textSelectionEnabled'
:class='{"zoom-active": zoom > 40, "text-selection": textSelectionEnabled, "pdf-viewer-wrapper": true }'
style='position: relative'>
<vue-pdf ...
ref='pdf'
:style='{ width: zoom + "%" }'
:page='currentPage'
@page-loaded='onPageLoad' class='pdf-main' />
<!-- hidden text layer -->
<div
class="pdf-viewer--text-layer"
ref='textLayer'
:style='{left: textLayerViewport.left + "px", top: textLayerViewport.top + "px", height: textLayerViewport.height + "px", width: textLayerViewport.width + "px" }')
/>
</div>
</template>
</template>
<script>
const PDFJS = require('pdfjs-dist/build/pdf.js');
export default {
data() {
return {
textSelectionEnabled: false,
zoom: 40,
currentPage: 1,
textLayerViewport: {
left: 0,
top: 0,
height: 0,
width: 0,
}
}},
// when changing zoom = width of the wrapper div, rerun the text layer
watch: { zoom() { setTimeout(() => this.onPageLoad(), 150) } },
methods: {
onPageLoad() {
// currently, vue-pdf componentfactory wrapper does not export a function to get one specific page, so iterating over all
this.$refs.pdf.pdf.forEachPage((page) => {
if (page.pageIndex === this.currentPage - 1) {
return page.getTextContent()
.then(content => {
const rect = this.$refs.pdf.$refs.canvas.getBoundingClientRect()
this.$refs.textLayer.innerHTML = ""
this.textLayerViewport.left = rect.left + document.body.scrollLeft
this.textLayerViewport.top = rect.top + document.body.scrollTop
// because position: relative, the left and top are correct by default
this.textLayerViewport.left = 0
this.textLayerViewport.top = 0
this.textLayerViewport.height = this.$refs.pdf.$refs.canvas.height
this.textLayerViewport.width = this.$refs.pdf.$refs.canvas.width
// get the REAL scale comparing the current canvas width and the "normal" Viewport width at a scale of 1.0
const scale = this.$refs.pdf.$refs.canvas.width / page.getViewport(1).width
const viewport = page.getViewport(scale);
PDFJS.renderTextLayer({
textContent: content,
container: this.$refs.textLayer,
viewport: viewport,
textDivs: []
});
})
}
})
}
</script>
<style lang='scss'>
.pdf-viewer-wrapper {
overflow: hidden;
overflow-y: scroll;
max-height: 80vh;
background: #444;
overflow-scrolling: touch;
&::-webkit-scrollbar {
display: none;
}
&.zoom-active {
cursor: grab;
}
&.text-selection {
cursor: normal
}
}
.pdf-main {
margin: 30px auto;
}
.pdf-viewer--text-layer {
margin: 30px auto;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
opacity: 0.2;
line-height: 1.0;
::selection {
background-color: #FFA;
}
}
.pdf-viewer--text-layer > div {
color: transparent;
position: absolute;
white-space: pre;
cursor: text;
transform-origin: 0% 0%;
}
</style>
Is there any intention to implement this?
Dear @FranckFreiburger
Did you find time to implement text selection on canvas or with a text layer over it?
How do I get a working search field? Is it possible? How about text selection?