Skip to content
8 changes: 8 additions & 0 deletions examples/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
:show-customize-editor-add-draw="true"
:show-line-size-select = 'true'
:show-font-size-select= 'true'
:show-pagination="true"
:show-font-select="true"
:show-rename="true"
:show-save-btn="true"
Expand All @@ -24,6 +25,13 @@
:seal-image-hidden-on-save="false"
@onSave2Upload="save2Upload"
>
<template #pagination="{ pages, currentPage, onPageChange }">
<ul class="inline-flex">
<li @click="onPageChange(currentPage-1)">previous</li>
<p>{{ currentPage +1}}/{{ pages }}</p>
<li @click="onPageChange(currentPage+1)">next</li>
</ul>
</template>
</VuePdfEditor>

</div>
Expand Down
6 changes: 6 additions & 0 deletions src/Components/PDFPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ export default {
}
},
watch: {
page(){
this.render()
},
scale(newScale) {
this.dynamicScale = newScale // Monitor changes in the scale attribute and update dynamic scaling
this.render()
Expand All @@ -46,6 +49,9 @@ export default {
},
async render() {
const _page = await this.page

if(typeof _page ==='undefined') return

const canvas = this.$refs.canvas
const context = canvas.getContext('2d')
const viewport = _page.getViewport({
Expand Down
47 changes: 47 additions & 0 deletions src/Components/Pagination.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<div class="inline-flex -space-x-px text-sm">
<button :disabled="!canPreviousPage" class="flex items-center px-3 h-8 ms-0 leading-tight bg-blue-500 border border-e-0 rounded-s-lg hover:bg-blue-700 text-white font-bold disabled:dark:bg-blue-300" @click="onPreviousPage" :class="{'cursor-not-allowed': !canPreviousPage}">Previous</button>
<p class="flex items-center px-3 h-8 leading-tight text-white bg-blue-500 border border-gray-300 font-bold">{{ page }} Of {{ pages }}</p>
<button :disabled="!canNextPage" class="flex items-center px-3 h-8 ms-0 leading-tight bg-blue-500 border border-e-0 rounded-r-lg hover:bg-blue-700 text-white font-bold disabled:dark:bg-blue-300" @click="onNextPage" :class="{'cursor-not-allowed': !canNextPage}">Next</button>
</div>
</template>

<script>
export default {
name: 'PaginationComponent',
computed: {
page(){
return this.currentPage + 1
},
canNextPage(){
return this.currentPage + 1 <= this.pages - 1
},
canPreviousPage(){
return this.currentPage > 0
}
},
updated(){
this.$emit('onPageChange',this.currentPage)
},
props:{
pages: {
type: Number,
default: 0,
required: true,
},
currentPage: {
type: Number,
default: 0,
required: true
}
},
methods: {
onPreviousPage(){
this.$emit('update:current-page', this.currentPage-1)
},
onNextPage(){
this.$emit('update:current-page', this.currentPage+1)
},
}
}
</script>
87 changes: 48 additions & 39 deletions src/VuePdfEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
type="file"
name="pdf"
class="hidden"
accept="application/pdf"
@change="onUploadPDF">
<input id="image"
type="file"
Expand Down Expand Up @@ -76,6 +77,11 @@
@click="savePDF">
{{ saving ? 'saving' : 'keep' }}
</button>

<slot name="pagination" v-if="pages.length && showPagination" class="flex items-center gap-4" :pages="pages.length" :current-page="currentPage" :onPageChange="onPageChange">
<Pagination :pages="pages.length" :current-page.sync="currentPage" @onPageChange="onPageChange" />
</slot>

</div>
<div v-if="addingDrawing">
<div class="fixed z-10 top-0 left-0 right-0 border-b border-gray-300 bg-white shadow-lg"
Expand Down Expand Up @@ -106,27 +112,24 @@

<!-- PDF main body -->
<div class="w-full" style="text-align: center;">
<div v-for="(page,pIndex) in pages" :key="pIndex" style="display: inline-block;">
<div style="display: inline-block;">
<div class="p-5 items-center"
style="text-align: center"
@mousedown="selectPage(pIndex)"
@touchstart="selectPage(pIndex)">
style="text-align: center">
<div style="display: inline-block;"
class="relative shadow-lg"
:class="[pIndex === selectedPageIndex ?'shadowOutline':'']">
<PDFPage :ref="`page${pIndex}`"
class="relative shadow-lg">
<PDFPage :ref="`page${currentPage}`"
:scale="scale"
:data-key="pIndex"
:page="page"
@onMeasure="onMeasure($event, pIndex)" />
:data-key="currentPage"
:page="pages[currentPage]"
@onMeasure="onMeasure($event, currentPage)" />
<div class="absolute top-0 left-0 transform origin-top-left noTouchAction"
:style="{transform: `scale(${pagesScale[pIndex]})`}">
<div v-for="(object, oIndex) in allObjects[pIndex]" :key="oIndex">
:style="{transform: `scale(${pagesScale[currentPage]})`}">
<div v-for="(object, oIndex) in allObjects[currentPage]" :key="oIndex">
<div>
<div v-if="object.type === 'custom'">
<slot name="custom"
:object="object"
:pagesScale="pagesScale[pIndex]"
:pagesScale="pagesScale[currentPage]"
@onUpdate="updateObject(object.id, $event)"
@onDelete="deleteObject(object.id)" />
</div>
Expand All @@ -140,7 +143,7 @@
:height="object.height"
:origin-width="object.originWidth"
:origin-height="object.originHeight"
:page-scale="pagesScale[pIndex]"
:page-scale="pagesScale[currentPage]"
@onUpdate="updateObject(object.id, $event)"
@onDelete="deleteObject(object.id)" />
</div>
Expand All @@ -156,7 +159,7 @@
:line-height="object.lineHeight"
:font-family="object.fontFamily"
:current-page="object.currentPage"
:page-scale="pagesScale[pIndex]"
:page-scale="pagesScale[currentPage]"
@onUpdate="updateObject(object.id, $event)"
@onDelete="deleteObject(object.id)"
@onSelectFont="selectFontFamily" />
Expand All @@ -168,7 +171,7 @@
:width="object.width"
:origin-width="object.originWidth"
:origin-height="object.originHeight"
:page-scale="pagesScale[pIndex]"
:page-scale="pagesScale[currentPage]"
@onUpdate="updateObject(object.id, $event)"
@onDelete="deleteObject(object.id)" />
</div>
Expand All @@ -193,6 +196,7 @@
import { fetchFont } from './utils/prepareAssets.js'

import PDFPage from './Components/PDFPage.vue'
import Pagination from './Components/Pagination.vue'
import ImageItem from './Components/Image.vue'
import TextItem from './Components/TextItem.vue'
import Drawing from './Components/Drawing.vue'
Expand All @@ -216,6 +220,7 @@ export default {
TextIcon,
GestureIcon,
PencilIcon,
Pagination,
},
props: {
msg: String,
Expand All @@ -227,6 +232,10 @@ export default {
type: String,
default: '100%',
},
showPagination:{
type: Boolean,
default: false
},
showChooseFileBtn: {
type: Boolean,
default: false,
Expand Down Expand Up @@ -323,6 +332,7 @@ export default {
numPages: null,
pdfDocument: null,
pages: [],
currentPage: 0,
pagesScale: [],
allObjects: [],
currentFont: 'Courier',
Expand Down Expand Up @@ -375,7 +385,7 @@ export default {
}
try {
await this.addPDF(this.initFileSrc)
this.selectedPageIndex = 0
this.currentPage = 0
fetchFont(this.currentFont)
this.narrowEnlargeShow = true
this.initTextField()
Expand All @@ -390,17 +400,17 @@ export default {
}
},
initTextField() {
if (this.selectedPageIndex < 0 || this.initTextFields === null || this.initTextFields.length === 0) {
if (this.currentPage < 0 || this.initTextFields === null || this.initTextFields.length === 0) {
return
}
for (let i = 0; i < this.pages.length; i++) {
this.selectedPageIndex = i
this.currentPage = i
for (let j = 0; j < this.initTextFields.length; j++) {
const text = this.initTextFields[j]
this.addTextField(text, 0, j * 60, this.selectedPageIndex)
this.addTextField(text, 0, j * 60, this.currentPage)
}
}
this.selectedPageIndex = 0
this.currentPage = 0
const checker = setInterval(() => {
if (this.$refs.textItem.length === this.initTextFields.length * this.pages.length) {
document.getElementById('pdfBody').dispatchEvent(new MouseEvent('mousedown', {
Expand All @@ -414,11 +424,11 @@ export default {

},
async initImages() {
if (this.selectedPageIndex < 0) {
if (this.currentPage < 0) {
return
}
for (let i = 0; i < this.pages.length; i++) {
this.selectedPageIndex = i
this.currentPage = i
let y = 0
if (this.initImageUrls !== null && this.initImageUrls.length !== 0) {
// Need to initialize pictures
Expand All @@ -437,7 +447,7 @@ export default {
await this.addImage(await res.blob(), 0, (y + 1) * 100, 0.4, true)
}
}
this.selectedPageIndex = 0
this.currentPage = 0

},
onFinishDrawingCanvas(e) {
Expand All @@ -462,11 +472,11 @@ export default {
const files = e.target.files || (e.dataTransfer && e.dataTransfer.files)
const file = files[0]
if (!file || file.type !== 'application/pdf') return
this.selectedPageIndex = -1
this.currentPage = -1
try {
await this.addPDF(file)
this.narrowEnlargeShow = true
this.selectedPageIndex = 0
this.currentPage = 0
} catch (e) {
console.log(e)
}
Expand Down Expand Up @@ -516,7 +526,7 @@ export default {
},
async onUploadImage(e) {
const file = e.target.files[0]
if (file && this.selectedPageIndex >= 0) {
if (file && this.currentPage >= 0) {
await this.addImage(file)
}
e.target.value = null
Expand All @@ -536,7 +546,7 @@ export default {

const { canvasWidth, canvasHeight }
= this.$refs[
`page${this.selectedPageIndex}`
`page${this.currentPage}`
][0].getCanvasMeasurement()

const object = {
Expand All @@ -560,12 +570,12 @@ export default {
}
},
onAddTextField() {
if (this.selectedPageIndex >= 0) {
if (this.currentPage >= 0) {
this.addTextField()
}
},

addTextField(text = 'Please enter here', x = 0, y = 0, currentPage = this.selectedPageIndex) {
addTextField(text = 'Please enter here', x = 0, y = 0, currentPage = this.currentPage) {
const id = this.genID()
fetchFont(this.currentFont)
const object = {
Expand All @@ -584,7 +594,7 @@ export default {
},

onAddDrawing() {
if (this.selectedPageIndex >= 0) {
if (this.currentPage >= 0) {
this.addingDrawing = true
}
},
Expand All @@ -607,7 +617,7 @@ export default {

addObject(object) {
this.allObjects = this.allObjects.map((objects, pIndex) =>
pIndex === this.selectedPageIndex ? [...objects, object] : objects,
pIndex === this.currentPage ? [...objects, object] : objects,
)
},

Expand All @@ -617,13 +627,9 @@ export default {
this.currentFont = name
},

selectPage(index) {
this.selectedPageIndex = index
},

updateObject(objectId, payload) {
this.allObjects = this.allObjects.map((objects, pIndex) =>
pIndex === (payload.currentPage !== undefined ? payload.currentPage : this.selectedPageIndex)
pIndex === (payload.currentPage !== undefined ? payload.currentPage : this.currentPage)
? objects.map(object =>
object.id === objectId ? { ...object, ...payload } : object,
)
Expand All @@ -633,7 +639,7 @@ export default {

deleteObject(objectId) {
this.allObjects = this.allObjects.map((objects, pIndex) =>
pIndex === this.selectedPageIndex
pIndex === this.currentPage
? objects.filter(object => object.id !== objectId)
: objects,
)
Expand Down Expand Up @@ -680,7 +686,10 @@ export default {
this.saving = false
}
},
},
onPageChange(page){
this.currentPage = page
}
}
}
</script>

Expand Down