zdg #144
|
@ -1,8 +1,18 @@
|
||||||
<template>
|
pdfAdnFabric<template>
|
||||||
<div class="canvasitem">
|
<div class="canvasitem">
|
||||||
<div class="pdfAdnFabric" id="pdfAdnFabric">
|
<div class="pdfAdnFabric" id="pdfAdnFabric" >
|
||||||
<canvas id="pdf-fabric"></canvas>
|
<!-- @touchmove="handleTouchMove"
|
||||||
<canvas id="pdf-fabric1" v-if="props.pdfObj.numberOfPdf == 2"></canvas>
|
@touchend="handleTouchEnd"
|
||||||
|
@mousedown="handleMouseDown"
|
||||||
|
@mousemove="handleMouseMove"
|
||||||
|
@mouseup="handleMouseUp" -->
|
||||||
|
<div :class="ispointer ? 'ispointer' : ''">
|
||||||
|
<canvas ref="fabriccanvas" />
|
||||||
|
</div>
|
||||||
|
<!-- style="pointer-events: none;" -->
|
||||||
|
<div v-if="props.pdfObj.numberOfPdf === 2" :class="ispointer ? 'ispointer' : ''">
|
||||||
|
<canvas ref="fabriccanvas1" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -13,12 +23,20 @@ import {
|
||||||
onMounted,
|
onMounted,
|
||||||
watch,
|
watch,
|
||||||
reactive,
|
reactive,
|
||||||
|
defineProps,
|
||||||
|
defineExpose,
|
||||||
nextTick,
|
nextTick,
|
||||||
|
defineEmits,watchEffect
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
import { fabric } from 'fabric'
|
// import { fabric } from 'fabric'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { handleevent, savecanvsStore, initcanvasdata, displayData } from '@/utils/pdfAndFabric'
|
import { handleevent, savecanvsStore, initcanvasdata, displayData } from '@/utils/pdfAndFabric'
|
||||||
|
import { fabricVue, TYPES } from '@/plugins/fabric'
|
||||||
|
import { updateSmartBookMarkContent, addsmartBookMark,getBookMarkById } from '@/api/eTextbook/index'
|
||||||
|
import {useToolState} from '@/store/modules/tool'
|
||||||
|
const { ipcRenderer } = require('electron')
|
||||||
|
|
||||||
|
const toolState = useToolState();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
pdfObj: {
|
pdfObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -29,13 +47,16 @@ const props = defineProps({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const ispointer = ref(false) //是否画笔模式
|
||||||
// canvas的所有数据
|
// canvas的所有数据
|
||||||
const canvsStore = reactive({
|
const canvsStore = reactive({
|
||||||
id: 'xxxx',
|
|
||||||
pageArr: []
|
pageArr: []
|
||||||
})
|
})
|
||||||
const fabriccanvas = ref(null)
|
const fabriccanvas = ref(null)
|
||||||
const fabriccanvas1 = ref(null)
|
const fabriccanvas1 = ref(null)
|
||||||
|
|
||||||
|
const canvasFabricVue = ref(null)
|
||||||
|
const canvas1FabricVue = ref(null)
|
||||||
// 页面总数
|
// 页面总数
|
||||||
const numPagesTotal = ref(0)
|
const numPagesTotal = ref(0)
|
||||||
const imgarr = ref([])
|
const imgarr = ref([])
|
||||||
|
@ -47,9 +68,9 @@ const renderPage = async (canvasobj) => {
|
||||||
const pdf = await pdfjsLib.getDocument(props.pdfObj.pdfUrl).promise
|
const pdf = await pdfjsLib.getDocument(props.pdfObj.pdfUrl).promise
|
||||||
// 渲染当前页
|
// 渲染当前页
|
||||||
const page = await pdf.getPage(canvasobj.page)
|
const page = await pdf.getPage(canvasobj.page)
|
||||||
var screenWidth = window.innerWidth/2-100;
|
var screenWidth = window.innerWidth / 2 - 100
|
||||||
var screenHeight = window.innerHeight;
|
var screenHeight = window.innerHeight
|
||||||
const viewport = page.getViewport({ scale:2})
|
const viewport = page.getViewport({ scale: 2 })
|
||||||
|
|
||||||
const canvasElement = canvasobj.canvas
|
const canvasElement = canvasobj.canvas
|
||||||
canvasElement.width = viewport.width
|
canvasElement.width = viewport.width
|
||||||
|
@ -58,6 +79,8 @@ const renderPage = async (canvasobj) => {
|
||||||
canvasContext: canvasobj.context,
|
canvasContext: canvasobj.context,
|
||||||
viewport: viewport
|
viewport: viewport
|
||||||
}
|
}
|
||||||
|
// console.log(renderContext,22222222222222222222)
|
||||||
|
|
||||||
page.render(renderContext).promise.then((res) => {
|
page.render(renderContext).promise.then((res) => {
|
||||||
const img = document.createElement('img')
|
const img = document.createElement('img')
|
||||||
img.src = canvasobj.canvas.toDataURL('image/png')
|
img.src = canvasobj.canvas.toDataURL('image/png')
|
||||||
|
@ -68,34 +91,76 @@ const renderPage = async (canvasobj) => {
|
||||||
// 根据传过来的pdf对象 判断改渲染哪一个fabric
|
// 根据传过来的pdf对象 判断改渲染哪一个fabric
|
||||||
if (props.pdfObj.numberOfPdf == 2) {
|
if (props.pdfObj.numberOfPdf == 2) {
|
||||||
if (canvasobj.index == 0) {
|
if (canvasobj.index == 0) {
|
||||||
|
canvasFabricVue.value.canvas.setWidth(screenWidth)
|
||||||
fabriccanvas.value.setWidth(screenWidth)
|
canvasFabricVue.value.canvas.setHeight(screenHeight)
|
||||||
fabriccanvas.value.setHeight(screenHeight)
|
// updateCanvasBackgroundImage(canvasFabricVue,img)
|
||||||
displayData(fabriccanvas, canvsStore, canvasobj, fabric, img)
|
displayData(canvasFabricVue, canvsStore, canvasobj, fabric, img)
|
||||||
} else {
|
} else {
|
||||||
fabriccanvas1.value.setWidth(screenWidth)
|
canvas1FabricVue.value.canvas.setWidth(screenWidth)
|
||||||
fabriccanvas1.value.setHeight(screenHeight)
|
canvas1FabricVue.value.canvas.setHeight(screenHeight)
|
||||||
displayData(fabriccanvas1, canvsStore, canvasobj, fabric, img)
|
displayData(canvas1FabricVue, canvsStore, canvasobj, fabric, img)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fabriccanvas.value.setWidth(screenWidth)
|
canvasFabricVue.value.canvas.setHeight(screenHeight)
|
||||||
fabriccanvas.value.setHeight(screenHeight)
|
displayData(canvasFabricVue, canvsStore, canvasobj, fabric, img)
|
||||||
displayData(fabriccanvas, canvsStore, canvasobj, fabric, img)
|
|
||||||
}
|
}
|
||||||
// console.log(imgarr.value)
|
|
||||||
img.remove()
|
img.remove()
|
||||||
}
|
}
|
||||||
// 判断imgarr的JSONdata在canvsStore.pageArr有没有
|
// 判断imgarr的JSONdata在canvsStore.pageArr有没有
|
||||||
canvsStore.pageArr.forEach((item) => {
|
// canvsStore.pageArr.forEach((item) => {
|
||||||
if (item.page == canvasobj.page) {
|
// if (item.page == canvasobj.page) {
|
||||||
imgarr.value.forEach((img) => {
|
// imgarr.value.forEach((img) => {
|
||||||
if (img.page == canvasobj.page) {
|
// if (img.page == canvasobj.page) {
|
||||||
img.JSONdata = item.JSONdata
|
// img.JSONdata = item.JSONdata
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 保存数据
|
||||||
|
const savaDataStore = () => {
|
||||||
|
if(!toolState.isToolWin){
|
||||||
|
toolState.isPdfWin=false
|
||||||
|
toolState.showBoardAll=true //恢复默认值
|
||||||
|
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||||
|
ipcRenderer.send('open-PDF:minimize')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
imgarr.value.forEach((a) => {
|
||||||
|
if (a.index == 0) {
|
||||||
|
a.JSONdata = canvasFabricVue.value.canvas.toJSON()
|
||||||
|
} else {
|
||||||
|
a.JSONdata = canvas1FabricVue.value.canvas.toJSON()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const nameMap = new Map(canvsStore.pageArr.map((item) => [item.page, item.id]))
|
||||||
|
// 创建一个用于存储所有异步操作的数组
|
||||||
|
let promises = []
|
||||||
|
imgarr.value.forEach((item) => {
|
||||||
|
if (nameMap.has(item.page)) {
|
||||||
|
const params = {
|
||||||
|
id: nameMap.get(item.page),
|
||||||
|
contentData: JSON.stringify(item.JSONdata.objects)
|
||||||
|
}
|
||||||
|
promises.push(updateSmartBookMarkContent([params]))
|
||||||
|
} else {
|
||||||
|
promises.push(addsmartBookMark({
|
||||||
|
pageNum: item.page,
|
||||||
|
contentData: JSON.stringify(item.JSONdata.objects),
|
||||||
|
bookId: props.pdfObj.bookId,
|
||||||
|
type: '教材',
|
||||||
|
source: 'smarttalk'
|
||||||
|
}))
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
Promise.all(promises).then(res=>{
|
||||||
|
toolState.isPdfWin=false
|
||||||
|
toolState.showBoardAll=true //恢复默认值
|
||||||
|
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||||
|
ipcRenderer.send('open-PDF:minimize')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const updatePage = (canvasobj) => {
|
const updatePage = (canvasobj) => {
|
||||||
renderPage(canvasobj)
|
renderPage(canvasobj)
|
||||||
|
@ -105,16 +170,55 @@ const loadPdf = async (canvasobj) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const initPdf = async (type = 'default') => {
|
const initPdf = async (type = 'default') => {
|
||||||
|
imgarr.value.forEach((a) => {
|
||||||
|
if (a.index == 0) {
|
||||||
|
a.JSONdata = canvasFabricVue.value.canvas.toJSON()
|
||||||
|
} else {
|
||||||
|
a.JSONdata = canvas1FabricVue.value.canvas.toJSON()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 判断是否翻页以及工具窗口是否打开 满足 翻页+打开工具才能保存数据
|
||||||
|
if (type != 'default' && toolState.isToolWin) {
|
||||||
|
const nameMap = new Map(canvsStore.pageArr.map((item) => [item.page, item.id]))
|
||||||
|
// 创建一个用于存储所有异步操作的数组
|
||||||
|
let promises = []
|
||||||
|
imgarr.value.forEach((item) => {
|
||||||
|
if (nameMap.has(item.page)) {
|
||||||
|
const params = {
|
||||||
|
id: nameMap.get(item.page),
|
||||||
|
contentData: JSON.stringify(item.JSONdata.objects)
|
||||||
|
}
|
||||||
|
promises.push(updateSmartBookMarkContent([params]))
|
||||||
|
} else {
|
||||||
|
promises.push(addsmartBookMark({
|
||||||
|
pageNum: item.page,
|
||||||
|
contentData: JSON.stringify(item.JSONdata.objects),
|
||||||
|
bookId: props.pdfObj.bookId,
|
||||||
|
type: '教材',
|
||||||
|
source: 'smarttalk'
|
||||||
|
}))
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Promise.all(promises).then(res=>{
|
||||||
|
getBookMarkById(props.pdfObj.bookId).then(res=>{
|
||||||
|
const pageArr=getUniqueArrayByLastOccurrence(res.data)
|
||||||
|
canvsStore.pageArr=[]
|
||||||
|
pageArr.forEach((a) => {
|
||||||
|
canvsStore.pageArr.push({ page: a.pageNum, id: a.id, JSONdata: a.contentData })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
// 保存数据
|
// 保存数据
|
||||||
savecanvsStore(imgarr, canvsStore)
|
// savecanvsStore(imgarr, canvsStore)
|
||||||
// initcanvasdata(fabriccanvas)
|
|
||||||
// initcanvasdata(fabriccanvas1)
|
if (props.pdfObj.numberOfPdf == 1) {
|
||||||
// 单页模式
|
// imgarr.value[0]
|
||||||
if (type == 'restone') {
|
canvasFabricVue.value.history.clean()
|
||||||
// 清除 canvas 上的所有对象
|
} else {
|
||||||
fabriccanvas1.value.clear()
|
canvasFabricVue.value.history.clean()
|
||||||
// 释放 canvas 的资源
|
canvas1FabricVue.value.history.clean()
|
||||||
fabriccanvas1.value.dispose()
|
|
||||||
}
|
}
|
||||||
// 清除现有 canvas 元素的内容
|
// 清除现有 canvas 元素的内容
|
||||||
canvasNumbsValue.value.forEach((canvasObj) => {
|
canvasNumbsValue.value.forEach((canvasObj) => {
|
||||||
|
@ -146,7 +250,6 @@ const initPdf = async (type = 'default') => {
|
||||||
} else {
|
} else {
|
||||||
canvasNumbsValue.value[i].page = props.pdfObj.numPages + 1
|
canvasNumbsValue.value[i].page = props.pdfObj.numPages + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
canvasNumbsValue.value[i].index = i
|
canvasNumbsValue.value[i].index = i
|
||||||
// 加载FabricVue
|
// 加载FabricVue
|
||||||
await loadPdf(canvasNumbsValue.value[i])
|
await loadPdf(canvasNumbsValue.value[i])
|
||||||
|
@ -154,47 +257,144 @@ const initPdf = async (type = 'default') => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//根据page去重
|
||||||
|
const getUniqueArrayByLastOccurrence=(array)=> {
|
||||||
|
const uniqueItems = array.reduce((acc, current) => {
|
||||||
|
// 使用 Map 来跟踪最后一个出现的 pageNum 和它的对象
|
||||||
|
acc.set(current.pageNum, current);
|
||||||
|
return acc;
|
||||||
|
}, new Map());
|
||||||
|
|
||||||
|
// 将 Map 的值转换回数组
|
||||||
|
const resultArray = Array.from(uniqueItems.values());
|
||||||
|
|
||||||
|
return resultArray;
|
||||||
|
}
|
||||||
const initPdfone = async () => {
|
const initPdfone = async () => {
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
fabriccanvas1.value = new fabric.Canvas('pdf-fabric1')
|
const option = { freeDrawingCursor: 'default' }
|
||||||
fabriccanvas1.value.isDrawingMode = true
|
const canvas2 = new fabricVue()
|
||||||
fabriccanvas1.value.freeDrawingBrush.color = '#A33AFE'
|
await canvas2.initCanvas(fabriccanvas1.value, option)
|
||||||
fabriccanvas1.value.freeDrawingCursor = 'default'
|
canvas2.canvas.setWidth(window.innerWidth / 2 - 100)
|
||||||
fabriccanvas1.value.setWidth(860)
|
canvas1FabricVue.value = canvas2
|
||||||
handleevent(fabriccanvas1.value, imgarr, 'two')
|
await initPdf('addOnePage')
|
||||||
}, 0)
|
}, 0)
|
||||||
initPdf('addOnePage')
|
|
||||||
}
|
}
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
|
// 创建canvas转化成图片
|
||||||
const pdf = await pdfjsLib.getDocument(props.pdfObj.pdfUrl).promise
|
const pdf = await pdfjsLib.getDocument(props.pdfObj.pdfUrl).promise
|
||||||
numPagesTotal.value = pdf.numPages
|
numPagesTotal.value = pdf.numPages
|
||||||
// console.log(pdf)
|
|
||||||
// 初始化fabriccanvas
|
// 初始化fabriccanvas
|
||||||
fabriccanvas.value = new fabric.Canvas('pdf-fabric')
|
const option = { freeDrawingCursor: 'default' }
|
||||||
fabriccanvas.value.setWidth(860)
|
const canvas1 = new fabricVue()
|
||||||
fabriccanvas.value.isDrawingMode = true
|
// canvas1.boardConfig.mode= TYPES.ActionMode.OTHER
|
||||||
fabriccanvas.value.freeDrawingBrush.color = '#A33AFE'
|
// canvas1.boardConfig.mode= TYPES.ActionMode.ERASE
|
||||||
fabriccanvas.value.freeDrawingCursor = 'default'
|
await canvas1.initCanvas(fabriccanvas.value, option)
|
||||||
|
canvas1.canvas.setWidth(window.innerWidth / 2 - 100)
|
||||||
fabriccanvas1.value = new fabric.Canvas('pdf-fabric1')
|
canvasFabricVue.value = canvas1
|
||||||
fabriccanvas1.value.isDrawingMode = true
|
const canvas2 = new fabricVue()
|
||||||
fabriccanvas1.value.freeDrawingBrush.color = '#A33AFE'
|
await canvas2.initCanvas(fabriccanvas1.value, option)
|
||||||
fabriccanvas1.value.freeDrawingCursor = 'default'
|
canvas2.canvas.setWidth(window.innerWidth / 2 - 100)
|
||||||
fabriccanvas1.value.setWidth(860)
|
// canvas2.canvas.isDrawingMode=false
|
||||||
|
canvas1FabricVue.value = canvas2
|
||||||
|
window.test = { canvas1, canvas2 }
|
||||||
emit('update:numPagesTotal', pdf.numPages)
|
emit('update:numPagesTotal', pdf.numPages)
|
||||||
initPdf()
|
|
||||||
|
if (props.pdfObj.allPageData.length) {
|
||||||
|
props.pdfObj.allPageData.forEach((a) => {
|
||||||
|
if (a.pageNum == 1 || a.pageNum == 2) {
|
||||||
|
canvsStore.pageArr.push({ page: a.pageNum, id: a.id, JSONdata: a.contentData })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await initPdf()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
ElMessage.error('pdf文件错误')
|
ElMessage.error('pdf文件错误')
|
||||||
}
|
}
|
||||||
|
setToolStatus()
|
||||||
// 监听2个canvas事件
|
// 监听2个canvas事件
|
||||||
handleevent(fabriccanvas.value, imgarr)
|
// handleevent(fabriccanvas.value, imgarr)
|
||||||
handleevent(fabriccanvas1.value, imgarr, 'two')
|
// handleevent(fabriccanvas1.value, imgarr, 'two')
|
||||||
})
|
})
|
||||||
|
// zdg: 设置-底部工具栏-状态
|
||||||
|
const setToolStatus = () => {
|
||||||
|
toolState.showBoardAll = false
|
||||||
|
}
|
||||||
|
// 判断元素是否加载完成
|
||||||
|
const handleMode = (vale,type)=>{
|
||||||
|
if(vale=='select'){
|
||||||
|
ispointer.value=true
|
||||||
|
}else{
|
||||||
|
ispointer.value=false
|
||||||
|
}
|
||||||
|
switch(vale) {
|
||||||
|
case 'select': // 选择模式
|
||||||
|
canvasFabricVue.value?.handleMode(TYPES.ActionMode.OTHER)
|
||||||
|
canvas1FabricVue.value?.handleMode(TYPES.ActionMode.OTHER)
|
||||||
|
break
|
||||||
|
case 'brush': // 画笔模式
|
||||||
|
canvasFabricVue.value?.handleMode(TYPES.ActionMode.DRAW)
|
||||||
|
canvasFabricVue.value.canvas.freeDrawingCursor = 'default'
|
||||||
|
canvas1FabricVue.value?.handleMode(TYPES.ActionMode.DRAW)
|
||||||
|
canvas1FabricVue.value.canvas.freeDrawingCursor = 'default'
|
||||||
|
break
|
||||||
|
case 'erase': // 板擦模式
|
||||||
|
canvasFabricVue.value?.handleMode(TYPES.ActionMode.ERASE)
|
||||||
|
canvas1FabricVue.value?.handleMode(TYPES.ActionMode.ERASE)
|
||||||
|
break
|
||||||
|
case 'clear': // 清空画布
|
||||||
|
clearCanvas()
|
||||||
|
// canvas1FabricVue.value.history?.clean()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 清空canvas
|
||||||
|
const clearCanvas=()=>{
|
||||||
|
if(canvasFabricVue.value){
|
||||||
|
const objects = canvasFabricVue.value.canvas.getObjects();
|
||||||
|
objects.forEach((obj) => {
|
||||||
|
// 检查对象是否是背景
|
||||||
|
if (obj !== canvasFabricVue.value.canvas.backgroundImage) {
|
||||||
|
// 删除背景之外的对象
|
||||||
|
canvasFabricVue.value.canvas.remove(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvasFabricVue.value.canvas.renderAll();
|
||||||
|
}
|
||||||
|
if(canvas1FabricVue.value){
|
||||||
|
const objects = canvas1FabricVue.value.canvas.getObjects();
|
||||||
|
objects.forEach((obj) => {
|
||||||
|
// 检查对象是否是背景
|
||||||
|
if (obj !== canvas1FabricVue.value.canvas.backgroundImage) {
|
||||||
|
// 删除背景之外的对象
|
||||||
|
canvas1FabricVue.value.canvas.remove(obj);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas1FabricVue.value.canvas.renderAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const watchToolState=()=>{
|
||||||
|
if(toolState.showBoardAll){
|
||||||
|
setTimeout(() => {
|
||||||
|
toolState.showBoardAll=false
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
// 加载工具
|
||||||
|
handleMode(toolState.model)
|
||||||
|
|
||||||
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
initPdf,
|
initPdf,
|
||||||
initPdfone
|
initPdfone,
|
||||||
|
savaDataStore
|
||||||
|
})
|
||||||
|
watchEffect(() => {
|
||||||
|
console.log(toolState.model,'监听')
|
||||||
|
watchToolState() //监听工具栏
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -204,6 +404,8 @@ defineExpose({
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: 100vh;
|
||||||
}
|
}
|
||||||
.pdfAdnFabric {
|
.pdfAdnFabric {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -214,4 +416,7 @@ defineExpose({
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.ispointer {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -1,15 +1,9 @@
|
||||||
pdfAdnFabric<template>
|
pdfAdnFabric<template>
|
||||||
<div class="canvasitem">
|
<div class="canvasitem">
|
||||||
<div class="pdfAdnFabric" id="pdfAdnFabric" >
|
<div class="pdfAdnFabric" id="pdfAdnFabric" >
|
||||||
<!-- @touchmove="handleTouchMove"
|
|
||||||
@touchend="handleTouchEnd"
|
|
||||||
@mousedown="handleMouseDown"
|
|
||||||
@mousemove="handleMouseMove"
|
|
||||||
@mouseup="handleMouseUp" -->
|
|
||||||
<div :class="ispointer ? 'ispointer' : ''">
|
<div :class="ispointer ? 'ispointer' : ''">
|
||||||
<canvas ref="fabriccanvas" />
|
<canvas ref="fabriccanvas" />
|
||||||
</div>
|
</div>
|
||||||
<!-- style="pointer-events: none;" -->
|
|
||||||
<div v-if="props.pdfObj.numberOfPdf === 2" :class="ispointer ? 'ispointer' : ''">
|
<div v-if="props.pdfObj.numberOfPdf === 2" :class="ispointer ? 'ispointer' : ''">
|
||||||
<canvas ref="fabriccanvas1" />
|
<canvas ref="fabriccanvas1" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,7 +74,10 @@ const renderPage = async (canvasobj) => {
|
||||||
viewport: viewport
|
viewport: viewport
|
||||||
}
|
}
|
||||||
// console.log(renderContext,22222222222222222222)
|
// console.log(renderContext,22222222222222222222)
|
||||||
|
// const textContent = await page.getTextContent();
|
||||||
|
// console.log(textContent);
|
||||||
|
// const annotations = await page.getAnnotations();
|
||||||
|
// console.log(annotations);
|
||||||
page.render(renderContext).promise.then((res) => {
|
page.render(renderContext).promise.then((res) => {
|
||||||
const img = document.createElement('img')
|
const img = document.createElement('img')
|
||||||
img.src = canvasobj.canvas.toDataURL('image/png')
|
img.src = canvasobj.canvas.toDataURL('image/png')
|
||||||
|
@ -106,22 +103,12 @@ const renderPage = async (canvasobj) => {
|
||||||
}
|
}
|
||||||
img.remove()
|
img.remove()
|
||||||
}
|
}
|
||||||
// 判断imgarr的JSONdata在canvsStore.pageArr有没有
|
|
||||||
// canvsStore.pageArr.forEach((item) => {
|
|
||||||
// if (item.page == canvasobj.page) {
|
|
||||||
// imgarr.value.forEach((img) => {
|
|
||||||
// if (img.page == canvasobj.page) {
|
|
||||||
// img.JSONdata = item.JSONdata
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 保存数据
|
// 保存数据
|
||||||
const savaDataStore = () => {
|
const savaDataStore = () => {
|
||||||
if(!toolState.isToolWin){
|
if(!toolState.isToolWin){
|
||||||
toolState.isPdfWin=false
|
toolState.isPdfWin=false
|
||||||
toolState.showBoardAll=true //恢复默认值
|
toolState.showBoardAll=true //恢复默认值
|
||||||
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||||
ipcRenderer.send('open-PDF:minimize')
|
ipcRenderer.send('open-PDF:minimize')
|
||||||
|
@ -393,8 +380,16 @@ defineExpose({
|
||||||
savaDataStore
|
savaDataStore
|
||||||
})
|
})
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
console.log(toolState.model,'监听')
|
console.log(toolState.isToolWin,'监听')
|
||||||
watchToolState() //监听工具栏
|
console.log(toolState,'监听111')
|
||||||
|
if(toolState.isToolWin){
|
||||||
|
ispointer.value=false
|
||||||
|
}else{
|
||||||
|
ispointer.value=true
|
||||||
|
}
|
||||||
|
if(toolState.isPdfWin){
|
||||||
|
watchToolState() //监听工具栏
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
// 所有事件
|
|
||||||
export function handleevent(canvas, imgarr, type = 'defalut') {
|
|
||||||
// // 鼠标按下
|
|
||||||
// canvas.on('mouse:down', function (e) {})
|
|
||||||
// // // 监听鼠标移动事件
|
|
||||||
// // canvas.on('mouse:move', (options) => {
|
|
||||||
// // console.log('Mouse move event:', options);
|
|
||||||
// // });
|
|
||||||
|
|
||||||
// // 监听鼠标释放事件
|
|
||||||
// canvas.on('mouse:up', (options) => {
|
|
||||||
// //判断是点击的哪一个
|
|
||||||
// if (type == 'defalut') {
|
|
||||||
// if (imgarr.value[0].index == 0) {
|
|
||||||
// imgarr.value[0].JSONdata = canvas.toJSON()
|
|
||||||
// }
|
|
||||||
// if (imgarr.value[1]?.index == 0) {
|
|
||||||
// imgarr.value[1].JSONdata = canvas.toJSON()
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (imgarr.value[0].index == 1) {
|
|
||||||
// imgarr.value[0].JSONdata = canvas.toJSON()
|
|
||||||
// }
|
|
||||||
// if (imgarr.value[1]?.index == 1) {
|
|
||||||
// imgarr.value[1].JSONdata = canvas.toJSON()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// console.log(imgarr.value)
|
|
||||||
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
// 保存数据
|
|
||||||
export function savecanvsStore(imgarr, canvsStore) {
|
|
||||||
// canvsStore.pageArr = mergeAndReplace(canvsStore.pageArr, imgarr.value)
|
|
||||||
}
|
|
||||||
// 重显数据
|
|
||||||
export function displayData(canvas, canvsStore, canvasobj, fabric, img) {
|
|
||||||
// // 初始化
|
|
||||||
// if (!canvsStore.pageArr.length) {
|
|
||||||
// fabric.Image.fromURL(img.src, (img) => {
|
|
||||||
// img.set({
|
|
||||||
// left: 0,
|
|
||||||
// top: 0,
|
|
||||||
// scaleX: canvas.value.width / img.width,
|
|
||||||
// scaleY: canvas.value.height / img.height
|
|
||||||
// })
|
|
||||||
// canvas.value.setBackgroundImage(img, canvas.value.renderAll.bind(canvas.value))
|
|
||||||
// })
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// canvsStore.pageArr.forEach((item) => {
|
|
||||||
// //初始化
|
|
||||||
// if (item.page == canvasobj.page) {
|
|
||||||
// // canvas.value.clear() // 清除 Canvas
|
|
||||||
// // console.log(item.JSONdata, '找到一样的数据')
|
|
||||||
// canvas.value.loadFromJSON(item.JSONdata, () => {
|
|
||||||
// // 在所有对象加载完成后重新渲染画布
|
|
||||||
// canvas.value.renderAll.bind(canvas.value)
|
|
||||||
// canvas.value.renderAll()
|
|
||||||
// // requestAnimationFrame(() => {
|
|
||||||
// // // 渲染所有对象
|
|
||||||
|
|
||||||
// // })
|
|
||||||
// })
|
|
||||||
// } else {
|
|
||||||
// // 使用 requestAnimationFrame 来更新画布,确保在下一帧进行重绘
|
|
||||||
// // // 清除 Canvas
|
|
||||||
// canvas.value.clear()
|
|
||||||
// requestAnimationFrame(function () {
|
|
||||||
// fabric.Image.fromURL(img.src, (img) => {
|
|
||||||
// img.set({
|
|
||||||
// left: 0,
|
|
||||||
// top: 0,
|
|
||||||
// scaleX: canvas.value.width / img.width,
|
|
||||||
// scaleY: canvas.value.height / img.height
|
|
||||||
// })
|
|
||||||
// canvas.value.setBackgroundImage(img, canvas.value.renderAll.bind(canvas.value))
|
|
||||||
// })
|
|
||||||
// // 渲染所有对象
|
|
||||||
// canvas.value.renderAll.bind(canvas.value)
|
|
||||||
// canvas.value.renderAll()
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
//page 一样替换
|
|
||||||
const mergeAndReplace = (arr1, arr2) => {
|
|
||||||
// // 用于存储替换后的数组
|
|
||||||
// const resultArray = array1.map(item1 => {
|
|
||||||
// // 在 array2 中查找 page 相同的对象
|
|
||||||
// const replacement = array2.find(item2 => item2.page == item1.page);
|
|
||||||
// // 如果找到替换对象,则返回替换对象,否则返回原对象
|
|
||||||
// return replacement ? replacement : item1;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // 将 array2 中 page 不在 array1 中的对象追加到结果数组中
|
|
||||||
// array2.forEach(item2 => {
|
|
||||||
// const existsInArray1 = array1.some(item1 => item1.page == item2.page);
|
|
||||||
// if (!existsInArray1) {
|
|
||||||
// resultArray.push(item2);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return resultArray;
|
|
||||||
|
|
||||||
// 创建一个映射,将 arr2 中的对象按 page 属性存储
|
|
||||||
let map = new Map(arr2.map((item) => [item.page, item]))
|
|
||||||
|
|
||||||
// 使用 map 替换 arr1 中相应 page 的对象,并添加 arr2 中的对象
|
|
||||||
arr1 = arr1.map((item) => (map.has(item.page) ? map.get(item.page) : item))
|
|
||||||
|
|
||||||
// 将 map 中存在但 arr1 中不存在的对象添加到 arr1
|
|
||||||
for (let [page, obj] of map) {
|
|
||||||
if (!arr1.some((item) => item.page === page)) {
|
|
||||||
arr1.push(obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arr1
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化数据
|
|
||||||
export function initcanvasdata(canvas) {
|
|
||||||
canvas.value.clear() // 清除 Canvas
|
|
||||||
// 设置画布的背景色或其他属性
|
|
||||||
canvas.value.backgroundColor = 'rgba(255, 255, 255, 1)' // 白色背景
|
|
||||||
|
|
||||||
// 使用 requestAnimationFrame 来更新画布,确保在下一帧进行重绘
|
|
||||||
requestAnimationFrame(function () {
|
|
||||||
// 渲染所有对象
|
|
||||||
canvas.value.renderAll.bind(canvas.value)
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -82,6 +82,7 @@ export function ipcHandle(fn,key, cb) {
|
||||||
* @param {*} data 参数
|
* @param {*} data 参数
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
let winPdf=null
|
||||||
export const createWindow = async (type, data) => {
|
export const createWindow = async (type, data) => {
|
||||||
if (!type) return console.error('createWindow: type is null')
|
if (!type) return console.error('createWindow: type is null')
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
@ -117,12 +118,19 @@ export const createWindow = async (type, data) => {
|
||||||
}
|
}
|
||||||
data.isConsole = true // 是否开启控制台
|
data.isConsole = true // 是否开启控制台
|
||||||
data.option = {...defOption, ...option}
|
data.option = {...defOption, ...option}
|
||||||
|
if(winPdf){ //判断是否已经打开
|
||||||
|
// if (winPdf.isMinimized()) winPdf.restore();
|
||||||
|
winPdf.focus();
|
||||||
|
// toolState.isPdfWin=true
|
||||||
|
return
|
||||||
|
}
|
||||||
const win = await toolWindow(data)
|
const win = await toolWindow(data)
|
||||||
win.type = type // 唯一标识
|
win.type = type // 唯一标识
|
||||||
win.show()
|
win.show()
|
||||||
win.setFullScreen(true) // 设置窗口为全屏
|
win.setFullScreen(true) // 设置窗口为全屏
|
||||||
// win.webContents.openDevTools() // 打开调试工具
|
// win.webContents.openDevTools() // 打开调试工具
|
||||||
eventHandles(type, win) // 事件监听处理
|
eventHandles(type, win) // 事件监听处理
|
||||||
|
winPdf=win
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -189,7 +197,7 @@ const eventHandles = (type, win) => {
|
||||||
// 公共方法
|
// 公共方法
|
||||||
const publicMethods = ({onClosed}={}) => {
|
const publicMethods = ({onClosed}={}) => {
|
||||||
// 监听主窗口-关闭事件
|
// 监听主窗口-关闭事件
|
||||||
mainWin.once('close', () => {win.destroy()})
|
mainWin.once('close', () => {winPdf=null;win.destroy();})
|
||||||
win.on('closed', () => {
|
win.on('closed', () => {
|
||||||
if(onClosed) onClosed() // 自定义关闭事件
|
if(onClosed) onClosed() // 自定义关闭事件
|
||||||
win = null
|
win = null
|
||||||
|
@ -217,8 +225,12 @@ const eventHandles = (type, win) => {
|
||||||
break}
|
break}
|
||||||
case 'open-PDF': {
|
case 'open-PDF': {
|
||||||
// 最小化窗口 minimize()
|
// 最小化窗口 minimize()
|
||||||
Remote.ipcMain.once('open-PDF:minimize', () => {win&&win.destroy()})
|
Remote.ipcMain.once('open-PDF:minimize', () => {
|
||||||
publicMethods() // 加载公共方法
|
winPdf=null
|
||||||
|
win&&win.destroy()
|
||||||
|
// win&&win.minimize(); //缩小功能
|
||||||
|
})
|
||||||
|
publicMethods() // 加载公共方法
|
||||||
break}
|
break}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
|
|
@ -40,9 +40,6 @@ import { getStaticUrl } from '@/utils/tool'
|
||||||
const { ipcRenderer } = require('electron')
|
const { ipcRenderer } = require('electron')
|
||||||
import { getBookMarkById } from '@/api/eTextbook/index'
|
import { getBookMarkById } from '@/api/eTextbook/index'
|
||||||
import {useToolState} from '@/store/modules/tool'
|
import {useToolState} from '@/store/modules/tool'
|
||||||
// const getStaticUrl=(url)=>{
|
|
||||||
// return url
|
|
||||||
// }
|
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc = getStaticUrl('/lib/build/pdf.worker.mjs')
|
pdfjsLib.GlobalWorkerOptions.workerSrc = getStaticUrl('/lib/build/pdf.worker.mjs')
|
||||||
const toolState = useToolState();
|
const toolState = useToolState();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -108,7 +105,8 @@ const switchPageMode = () => {
|
||||||
}
|
}
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
toolState.isPdfWin=true
|
toolState.isPdfWin=true
|
||||||
pdfObj.pdfUrl = getStaticUrl(route.query.path, 'user', 'selfFile', true)
|
// pdfObj.pdfUrl = getStaticUrl(route.query.path, 'user', 'selfFile', true)
|
||||||
|
pdfObj.pdfUrl = getStaticUrl('aaa.pdf', 'user', 'selfFile', true) //本地
|
||||||
textbookId.value = route.query.textbookId
|
textbookId.value = route.query.textbookId
|
||||||
pdfObj.bookId=textbookId.value
|
pdfObj.bookId=textbookId.value
|
||||||
getBookMarkById(textbookId.value).then(res=>{
|
getBookMarkById(textbookId.value).then(res=>{
|
||||||
|
|
|
@ -173,7 +173,7 @@ export default {
|
||||||
timerId: null,
|
timerId: null,
|
||||||
// 布置作业弹窗
|
// 布置作业弹窗
|
||||||
setDialog: false,
|
setDialog: false,
|
||||||
row: ''
|
row: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -536,9 +536,10 @@ export default {
|
||||||
// 打开PDF-课件
|
// 打开PDF-课件
|
||||||
async navtoPdf() {
|
async navtoPdf() {
|
||||||
const toolStore = useToolState()
|
const toolStore = useToolState()
|
||||||
if (toolStore.isPdfWin) return this.$message.error('您当前已打开课本,请勿重复操作')
|
// if (toolStore.isPdfWin) return this.$message.error('您当前已打开课本,请勿重复操作')
|
||||||
let path = await this.getBookPathFromServer()
|
let path = await this.getBookPathFromServer()
|
||||||
path=path.replace(/^.*[\\\/]/, '');
|
path=path.replace(/^.*[\\\/]/, '');
|
||||||
|
console.log(path)
|
||||||
// console.log(this.uploadData.textbookId)
|
// console.log(this.uploadData.textbookId)
|
||||||
createWindow('open-PDF', { url: '/classBegins/index?textbookId='+this.uploadData.textbookId+'&path='+ path })
|
createWindow('open-PDF', { url: '/classBegins/index?textbookId='+this.uploadData.textbookId+'&path='+ path })
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue