这个功能主要实现批阅的,修改上传的图片,标记内容
看看效果图
主要是根据fabric这个库来进行完成的
下载包
npm i fabric
组件内注册使用
import { fabric } from 'fabric';
步骤
body中
<divv-if="imgs.length"class="canvas-wraper"style="overflow-y: auto; position: relative"><div class="lefts1" @click="changeZuo(1)">{{ zuo }}</div> // 左切换按钮<div style="overflow: auto"><canvas id="canvas" ref="canvas"> </canvas> // 动态的渲染画布</div><div class="lefts" @click="changeZuo(2)"> {{ you }}</div> // 右切换按钮</div><div v-else class="canvas-wraper"> // 如果没有图片显示空<a-empty /></div></div><div style="background: #fff; padding: 20px; flex: 1"><divstyle="background: #f2f4f8; height: 100%; width: 100%; padding: 10px"><div><color-picker @changeColor="changeColors" @changeCuxi="changeCuxi" // 使用的颜色库/></div><a-dividerdashedstyle="border-color: rgb(204, 204, 204); margin-top: 10px"/><div style="margin: 10px 0"><div>预习报告</div><div><template v-for="(item, index) in yxReportFileUrl"><imgclass="reportImg":src="item.url"@click="changeImg(item.url, index)"/></template></div></div><a-dividerdashedstyle="border-color: rgb(204, 204, 204); margin-top: 10px"/><div style="margin: 10px 0"><div>实操作及课后报告</div><div><template v-for="(item, index) in reportFileUrl"><imgclass="reportImg":src="item.url"@click="changeImg(item.url, yxReportFileUrl.length - 1 + index)"/></template></div></div><a-dividerdashedstyle="border-color: rgb(204, 204, 204); margin-top: 10px"/><div style="margin: 10px 0"><div style="display: flex; align-items: center"><div style="margin-right: 10px">预习分数:</div><a-inputv-model:value="reportData.prepareScore"placeholder="请输入"style="width: 300px"/></div></div><a-dividerdashedstyle="border-color: rgb(204, 204, 204); margin-top: 10px"/><div style="margin: 10px 0"><div style="display: flex; align-items: center"><div style="margin-right: 10px">操作分数:</div><a-inputv-model:value="reportData.experimentScore"placeholder="请输入"style="width: 300px"/></div></div><a-dividerdashedstyle="border-color: rgb(204, 204, 204); margin-top: 10px"/><div style="margin: 10px 0"><div style="display: flex; align-items: center"><div style="margin-right: 10px">课后分数:</div><a-inputv-model:value="reportData.reportScore"placeholder="请输入"style="width: 300px"/></div></div><a-dividerdashedstyle="border-color: rgb(204, 204, 204); margin-top: 10px"/><!-- 三个按钮,上一个,下一个,返回课程列表页--><div style="margin: 30px 0"><a-buttonstyle="background: #2d8cf0; color: #fff; border-radius: 6px"@click="changeUser(1)">上一个</a-button><a-buttonstyle="margin: 0 30px;background: #19be6b;color: #fff;border-radius: 6px;"@click="changeUser(2)">下一个</a-button><a-button@click="goBack"style="background: #2d8cf0; color: #fff; border-radius: 6px">返回课程列表页</a-button></div><!-- <div class="download">--> // 可以进行查看当前批阅后的图片<!-- <button type="button" :disabled="done" @click="downLoadImage">--><!-- 转换为base64并预览--><!-- </button>--><!-- <img :src="imageBase64" v-show="imageBase64 != ''" alt="" />--><!-- </div>--></div>
js部分,主要是把要批阅的图片设置为背景图片进行标记批阅
<script>import { fabric } from 'fabric';import ColorPicker from '@/views/marking-report/components/color-picker.vue';import { changeColor } from 'ele-admin-pro/es';import ScorePicker from '@/views/marking-report/components/score-picker.vue';import {getCourseScore,pyStudentScore,updateCourseScoreById} from '@/api/marking-report';import { message } from 'ant-design-vue/es';import { uploadBase64File } from '@/api/system/file';// import { formatDate } from '@vueuse/shared';export default {components: { ScorePicker, ColorPicker },// 获取propsprops: ['data', 'data1'],data() {return {userIndex: 0,student: [],imgBase64: undefined,currentTool: '',yxReportFileUrl: [],reportFileUrl: [],imgs: [],imgsIndex: 0,currentImg: new Image(),done: false,fabricObj: null,initIdx: 0,zuo: '<',you: '>',toolsArr: [{ name: 'pencil', icon: ' icon-pencil', keyBoard: 'A' },{ name: 'duigou1', icon: 'icon-duigou1', keyBoard: 'B' },{ name: 'cuowu', icon: 'icon-cuowu', keyBoard: 'C' },{ name: 'line', icon: ' icon-line', keyBoard: 'D' },{ name: 'arrow', icon: ' icon-arrow', keyBoard: 'E' },{ name: 'xuxian', icon: ' icon-xuxian', keyBoard: 'F' },{ name: 'text', icon: ' icon-ziti', keyBoard: 'G' },{ name: 'juxing', icon: ' icon-juxing', keyBoard: 'H' },{ name: 'cricle', icon: ' icon-yuanxing', keyBoard: 'I' },{ name: 'ellipse', icon: ' icon-tuoyuanxing', keyBoard: 'J' },{ name: 'equilateral', icon: ' icon-sanjiaoxing', keyBoard: 'K' },{ name: 'remove', icon: ' icon-remove' },{ name: 'reset', icon: ' icon-reset' }],mouseFrom: {},mouseTo: {},moveCount: 1,doDrawing: false,fabricHistoryJson: [],mods: 0,drawingObject: null, //绘制对象drawColor: '#E34F51',drawWidth: 2,imageBase64: '',zoom: window.zoom ? window.zoom : 1,reportData: {},scoreId: ''};},computed: {canvasWidth() {return window.innerWidth;}},created() {},mounted() {this.getStudentScore();},beforeDestroy() {document.removeEventListener('keydown', this.onKeyDown);},methods: {// 切换学生changeUser(type) {// 根据type来区分上一个下一个,userIndex来进行切换if (type == 1) {if (this.userIndex == 0) {message.error('已经是第一个了');return;}this.userIndex--;// 保存当前图片跟分数// 调用downLoadImage方法得到转换后的图片;this.downLoadImage();setTimeout(() => {// 设置一个变量跟改变了的图片进行拼接let aa = this.imgs;aa[this.imgsIndex].url = this.imgBase64;// 遍历图片的url进行拼接let imgRes = '';if (this.imgs[this.imgsIndex].type == 're') {aa.forEach((item, index) => {if (item.type == 're') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});} else {aa.forEach((item, index) => {if (item.type == 'yx') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});}console.log(this.userIndex, 'this.userIndex');if (this.imgs[this.imgsIndex].type == 're') {updateCourseScoreById({scoreId: this.student[this.userIndex + 1].scoreId,correctFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片this.getCourseScoreActive(this.student[this.userIndex].scoreId,this.userIndex);// 提示保存成功message.success('保存成功');}});} else if (this.imgs[this.imgsIndex].type == 'yx') {updateCourseScoreById({scoreId: this.student[this.userIndex + 1].scoreId,yxCorrectFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片this.getCourseScoreActive(this.student[this.userIndex].scoreId,this.userIndex);// 提示保存成功message.success('保存成功');}});}}, 500);} else if (type == 2) {if (this.userIndex == this.student.length - 1) {message.error('已经是最后一个了');return;}this.userIndex++;// 调用downLoadImage方法得到转换后的图片;this.downLoadImage();setTimeout(() => {// 设置一个变量跟改变了的图片进行拼接let aa = this.imgs;aa[this.imgsIndex].url = this.imgBase64;// 遍历图片的url进行拼接let imgRes = '';if (this.imgs[this.imgsIndex].type == 're') {aa.forEach((item, index) => {if (item.type == 're') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});} else {aa.forEach((item, index) => {if (item.type == 'yx') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});}if (this.imgs[this.imgsIndex].type == 're') {updateCourseScoreById({scoreId: this.student[this.userIndex - 1].scoreId,correctFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片this.getCourseScoreActive(this.student[this.userIndex].scoreId,this.userIndex);// 提示保存成功message.success('保存成功');}});} else if (this.imgs[this.imgsIndex].type == 'yx') {updateCourseScoreById({scoreId: this.student[this.userIndex - 1].scoreId,yxCorrectFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片this.getCourseScoreActive(this.student[this.userIndex].scoreId,this.userIndex);// 提示保存成功message.success('保存成功');}});}}, 500);}},// 点击图片切换背景图changeImg(url, index) {this.imgsIndex = index;this.fabricObj.clear();this.setBackgroundImg(url);},// 获取分数change(value) {console.log(value, 'value');},// formatDate,// 切换图片changeZuo(type) {console.log(11, this.imgsIndex);if (type == 1) {if (this.imgsIndex == 0) {message.error('已经是第一张了');return;} else {// 调用downLoadImage方法得到转换后的图片;this.downLoadImage();setTimeout(() => {// 设置一个变量跟改变了的图片进行拼接let aa = this.imgs;aa[this.imgsIndex + 1].url = this.imgBase64;// 遍历图片的url进行拼接let imgRes = '';if (this.imgs[this.imgsIndex + 1].type == 're') {aa.forEach((item, index) => {if (item.type == 're') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});} else {aa.forEach((item, index) => {if (item.type == 'yx') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});}if (this.imgs[this.imgsIndex + 1].type == 're') {updateCourseScoreById({scoreId: this.scoreId,correctFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片console.log(this.imgs);this.imgs[this.imgsIndex + 1].url = this.imgBase64;// 提示保存成功message.success('保存成功');}});} else if (this.imgs[this.imgsIndex + 1].type == 'yx') {updateCourseScoreById({scoreId: this.scoreId,yxCorrectFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片console.log(this.imgs);this.imgs[this.imgsIndex + 1].url = this.imgBase64;// 提示保存成功message.success('保存成功');}});}}, 500);// 清空页面内容设置背景this.imgsIndex--;this.fabricObj.clear();this.setBackgroundImg(this.imgs[this.imgsIndex].url);}} else if ((type = 2)) {if (this.imgsIndex == this.imgs.length - 1) {message.error('已经是最后一张了');return;}// 调用downLoadImage方法得到转换后的图片;this.downLoadImage();setTimeout(() => {// 设置一个变量跟改变了的图片进行拼接let aa = this.imgs;aa[this.imgsIndex - 1].url = this.imgBase64;let imgRes = '';if (this.imgs[this.imgsIndex - 1].type == 're') {aa.forEach((item, index) => {if (item.type == 're') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});} else {aa.forEach((item, index) => {if (item.type == 'yx') {if (index == 0) {imgRes = item.url;} else {imgRes += ',' + item.url;}}});}if (this.imgs[this.imgsIndex - 1].type == 're') {updateCourseScoreById({scoreId: this.scoreId,correctFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片console.log(this.imgs);this.imgs[this.imgsIndex - 1].url = this.imgBase64;// 提示保存成功message.success('保存成功');}});} else if (this.imgs[this.imgsIndex - 1].type == 'yx') {updateCourseScoreById({scoreId: this.scoreId,yxCorrectFileUrl: imgRes,prepareScore: this.reportData.prepareScore,experimentScore: this.reportData.experimentScore,reportScore: this.reportData.reportScore}).then((res) => {console.log(res, 'res');if (res == '修改成功') {// 给this.imgss替换上一张图片this.imgs[this.imgsIndex - 1].url = this.imgBase64;// 提示保存成功message.success('保存成功');}});}}, 500);// 清空页面内容设置背景this.imgsIndex++;this.fabricObj.clear();this.setBackgroundImg(this.imgs[this.imgsIndex].url);}},changeColors(value) {this.drawColor = value;},changeCuxi(value) {this.drawWidth = value;},onKeyDown(event) {if (event.key >= 'A' && event.key <= 'K') {// 根据按键执行对应的操作switch (event.key) {case 'A':this.selectToolByName('pencil');break;case 'B':this.selectToolByName('duigou1');break;case 'C':this.selectToolByName('cuowu');break;case 'D':this.selectToolByName('line');break;case 'E':this.selectToolByName('arrow');break;case 'F':this.selectToolByName('xuxian');break;case 'G':this.selectToolByName('text');break;case 'H':this.selectToolByName('juxing');break;case 'I':this.selectToolByName('cricle');break;case 'J':this.selectToolByName('ellipse');break;case 'K':this.selectToolByName('equilateral');break;}}},selectToolByName(name) {// 选中指定名称的工具const tool = this.toolsArr.find((tool) => tool.name === name);if (tool) {this.handleTools(tool, this.toolsArr.indexOf(tool));}},changeColor,initCanvas() {console.log(88);console.log(this.imgs, 'this.imgs');setTimeout(() => {this.fabricObj = new fabric.Canvas('canvas', {isDrawingMode: false,selectable: true,selection: true});this.setBackgroundImg(this.imgs[0].url);this.imgsIndex = 0;//绑定画板事件document.addEventListener('keydown', this.onKeyDown);}, 500);},//时间监听fabricObjAddEvent() {this.fabricObj.on({'mouse:down': (o) => {this.mouseFrom.x = o.pointer.x;this.mouseFrom.y = o.pointer.y;this.doDrawing = true;if (this.currentTool == 'text') {this.drawText();}},'mouse:up': (o) => {this.mouseTo.x = o.pointer.x;this.mouseTo.y = o.pointer.y;this.drawingObject = null;this.moveCount = 1;this.doDrawing = false;this.updateModifications(true);},'mouse:move': (o) => {if (this.moveCount % 2 && !this.doDrawing) {//减少绘制频率return;}this.moveCount++;this.mouseTo.x = o.pointer.x;this.mouseTo.y = o.pointer.y;this.drawing();},//对象移动时间'object:moving': (e) => {e.target.opacity = 0.5;},//增加对象'object:added': (e) => {// debugger},'object:modified': (e) => {e.target.opacity = 1;let object = e.target;this.updateModifications(true);},'selection:created': (e) => {console.log(e, 'selection:created');if (e.e.target._objects) {//多选删除var etCount = e.e.target._objects.length;for (var etindex = 0; etindex < etCount; etindex++) {this.fabricObj.remove(e.e.target._objects[etindex]);}} else {//判断是否删除的是imgif (e.selected[0].type == 'image') {return;}this.fabricObj.remove(e.selected[0]);}this.fabricObj.discardActiveObject(); //清楚选中框this.updateModifications(true);}});},//储存历史记录updateModifications(savehistory) {if (savehistory == true) {this.fabricHistoryJson.push(JSON.stringify(this.fabricObj));}},//canvas 历史后退undo() {let state = this.fabricHistoryJson;if (this.mods < state.length) {this.fabricObj.clear().renderAll();this.fabricObj.loadFromJSON(state[state.length - 1 - this.mods - 1]);this.fabricObj.renderAll();this.mods += 1;}},//前进redo() {let state = this.fabricHistoryJson;if (this.mods > 0) {this.fabricObj.clear().renderAll();this.fabricObj.loadFromJSON(state[state.length - 1 - this.mods + 1]);this.fabricObj.renderAll();this.mods -= 1;}},transformMouse(mouseX, mouseY) {return { x: mouseX / this.zoom, y: mouseY / this.zoom };},resetObj() {this.fabricObj.selectable = false;this.fabricObj.selection = false;this.fabricObj.skipTargetFind = true;//清除文字对象if (this.textboxObj) {this.textboxObj.exitEditing();this.textboxObj = null;}},handleTools(tools, idx) {this.initIdx = idx;this.currentTool = tools.name;this.fabricObj.isDrawingMode = false;this.resetObj();switch (tools.name) {case 'pencil':this.fabricObj.isDrawingMode = true;// 设置画笔颜色this.fabricObj.freeDrawingBrush.color = this.drawColor;// 设置画笔宽度this.fabricObj.freeDrawingBrush.width = this.drawWidth;break;case 'remove':this.fabricObj.selection = true;this.fabricObj.skipTargetFind = false;this.fabricObj.selectable = true;break;case 'reset':// 清空页面内容this.fabricObj.clear();this.setBackgroundImg(this.currentImg.src);break;case 'redo':this.redo();break;case 'undo':this.undo();break;default:break;}},setBackgroundImg(imgUrl) {this.currentImg.src = imgUrl;// 重新更新获取最新imgUrl的高度let imgss = new Image();imgss.src = imgUrl;imgss.onload = function () {console.log(imgss.height, imgss.width);};// 重新更新高度setTimeout(() => {// 将图片的宽度设置为750this.fabricObj.setWidth(750);this.fabricObj.setHeight(750 * (imgss.height / imgss.width));let _this = this;_this.fabricObj.setBackgroundImage(this.currentImg.src,_this.fabricObj.renderAll.bind(_this.fabricObj),{ crossOrigin: 'anonymous' });}, 100);},//绘制文字对象drawText() {this.textboxObj = new fabric.Textbox(' ', {left: this.mouseFrom.x,top: this.mouseFrom.y,width: 220,fontSize: 18,fill: this.drawColor,hasControls: true});this.fabricObj.add(this.textboxObj);this.textboxObj.enterEditing();this.textboxObj.hiddenTextarea.focus();this.updateModifications(true);},drawing() {let _this = this;if (this.drawingObject) {this.fabricObj.remove(this.drawingObject);}let fabricObject = null;switch (this.currentTool) {case 'pencil':this.fabricObj.isDrawingMode = true;// 设置画笔颜色this.fabricObj.freeDrawingBrush.color = this.drawColor;// 设置画笔宽度this.fabricObj.freeDrawingBrush.width = this.drawWidth;break;case 'line':fabricObject = new fabric.Line([this.mouseFrom.x,this.mouseFrom.y,this.mouseTo.x,this.mouseTo.y],{stroke: this.drawColor,strokeWidth: this.drawWidth});break;case 'duigou1':fabricObject = new fabric.Path('M2.5 51.5c3 30 8.476 74.5 58 48.5 48-25.2 114.667-75.167 142-97',{left: this.mouseFrom.x,top: this.mouseFrom.y,stroke: this.drawColor,strokeWidth: this.drawWidth,fill: 'transparent' // 或者将这一行完全删除});break;case 'cuowu':fabricObject = new fabric.Path('M1 1L65.5 65.5M66 1L1.5 65.5', {left: this.mouseFrom.x,top: this.mouseFrom.y,stroke: this.drawColor,strokeWidth: this.drawWidth,fill: 'transparent' // 或者将这一行完全删除});break;case 'arrow':fabricObject = new fabric.Path(this.drawArrow(this.mouseFrom.x,this.mouseFrom.y,this.mouseTo.x,this.mouseTo.y,17.5,17.5),{stroke: this.drawColor,fill: 'rgba(255,255,255,0)',strokeWidth: this.drawWidth});break;case 'xuxian': //doshed linefabricObject = new fabric.Line([this.mouseFrom.x,this.mouseFrom.y,this.mouseTo.x,this.mouseTo.y],{strokeDashArray: [10, 3],stroke: this.drawColor,strokeWidth: this.drawWidth});break;case 'juxing': //矩形let path ='M ' +this.mouseFrom.x +' ' +this.mouseFrom.y +' L ' +this.mouseTo.x +' ' +this.mouseFrom.y +' L ' +this.mouseTo.x +' ' +this.mouseTo.y +' L ' +this.mouseFrom.x +' ' +this.mouseTo.y +' L ' +this.mouseFrom.x +' ' +this.mouseFrom.y +' z';fabricObject = new fabric.Path(path, {left: this.mouseFrom.x,top: this.mouseFrom.y,stroke: this.drawColor,strokeWidth: this.drawWidth,fill: 'rgba(255, 255, 255, 0)'});break;case 'cricle': //正圆let radius =Math.sqrt((this.mouseTo.x - this.mouseFrom.x) *(this.mouseTo.x - this.mouseFrom.x) +(this.mouseTo.y - this.mouseFrom.y) *(this.mouseTo.y - this.mouseFrom.y)) / 2;fabricObject = new fabric.Circle({left: this.mouseFrom.x,top: this.mouseFrom.y,stroke: this.drawColor,fill: 'rgba(255, 255, 255, 0)',radius: radius,strokeWidth: this.drawWidth});break;case 'ellipse': //椭圆let left = this.mouseFrom.x;let top = this.mouseFrom.y;let ellipse =Math.sqrt((this.mouseTo.x - left) * (this.mouseTo.x - left) +(this.mouseTo.y - top) * (this.mouseTo.y - top)) / 2;fabricObject = new fabric.Ellipse({left: left,top: top,stroke: this.drawColor,fill: 'rgba(255, 255, 255, 0)',originX: 'center',originY: 'center',rx: Math.abs(left - this.mouseTo.x),ry: Math.abs(top - this.mouseTo.y),strokeWidth: this.drawWidth});break;case 'equilateral': //等边三角形let height = this.mouseTo.y - this.mouseFrom.y;fabricObject = new fabric.Triangle({top: this.mouseFrom.y,left: this.mouseFrom.x,width: Math.sqrt(Math.pow(height, 2) + Math.pow(height / 2.0, 2)),height: height,stroke: this.drawColor,strokeWidth: this.drawWidth,fill: 'rgba(255,255,255,0)'});break;case 'remove':console.log('remove-----');break;default:// statements_def'break;}if (fabricObject) {this.fabricObj.add(fabricObject);this.drawingObject = fabricObject;}},//书写箭头的方法drawArrow(fromX, fromY, toX, toY, theta, headlen) {theta = typeof theta != 'undefined' ? theta : 30;headlen = typeof theta != 'undefined' ? headlen : 10;// 计算各角度和对应的P2,P3坐标let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI,angle1 = ((angle + theta) * Math.PI) / 180,angle2 = ((angle - theta) * Math.PI) / 180,topX = headlen * Math.cos(angle1),topY = headlen * Math.sin(angle1),botX = headlen * Math.cos(angle2),botY = headlen * Math.sin(angle2);let arrowX = fromX - topX,arrowY = fromY - topY;let path = ' M ' + fromX + ' ' + fromY;path += ' L ' + toX + ' ' + toY;arrowX = toX + topX;arrowY = toY + topY;path += ' M ' + arrowX + ' ' + arrowY;path += ' L ' + toX + ' ' + toY;arrowX = toX + botX;arrowY = toY + botY;path += ' L ' + arrowX + ' ' + arrowY;return path;},downLoadImage() {this.done = true;let base64URl = this.fabricObj.toDataURL({formart: 'jpg',multiplier: 1});this.imageBase64 = base64URl;uploadBase64File(base64URl).then((res) => {this.imgBase64 = res.url;});this.done = false;},getStudentScore() {// 获取左侧学生数据this.scoreId = this.data.scoreId;pyStudentScore({ cycleId: this.data.cycleId }).then((res) => {this.student = res;getCourseScore(this.scoreId).then((res) => {this.reportData = res;this.imgs = [];// 判断字符串是否为空,再判断是否有逗号if (res.correctFileUrl) {if (res.correctFileUrl.indexOf(',') > -1) {this.reportFileUrl = res.correctFileUrl.split(',');} else {this.reportFileUrl = [res.correctFileUrl];}} else if (res.reportFileUrl) {if (res.reportFileUrl.indexOf(',') > -1) {this.reportFileUrl = res.reportFileUrl.split(',');} else {this.reportFileUrl = [res.reportFileUrl];}}if (res.yxCorrectFileUrl) {if (res.yxCorrectFileUrl.indexOf(',') > -1) {this.yxReportFileUrl = res.yxCorrectFileUrl.split(',');} else {this.yxReportFileUrl = [res.yxCorrectFileUrl];}} else if (res.yxReportFileUrl) {if (res.yxReportFileUrl.indexOf(',') > -1) {this.yxReportFileUrl = res.yxReportFileUrl.split(',');} else {this.yxReportFileUrl = [res.yxReportFileUrl];}}// 给this.yxReportFileUrl和this.reportFileUrl添加字段yx和re区分this.yxReportFileUrl = this.yxReportFileUrl.map((item) => {return { url: item, type: 'yx' };});this.reportFileUrl = this.reportFileUrl.map((item) => {return { url: item, type: 're' };});this.imgs.push(...this.yxReportFileUrl);this.imgs.push(...this.reportFileUrl);//初始化canvasthis.initCanvas();setTimeout(() => {this.fabricObjAddEvent();}, 500);});});},// 点击切换背景色getCourseScoreActive(scoreId, index) {console.log(22221);this.scoreId = scoreId;this.userIndex = index;getCourseScore(scoreId).then((res) => {this.reportData = res;this.imgs = [];this.yxReportFileUrl = [];this.reportFileUrl = [];// 判断字符串是否为空,再判断是否有逗号if (res.correctFileUrl) {if (res.correctFileUrl.indexOf(',') > -1) {this.reportFileUrl = res.correctFileUrl.split(',');} else {this.reportFileUrl = [res.correctFileUrl];}} else if (res.reportFileUrl) {if (res.reportFileUrl.indexOf(',') > -1) {this.reportFileUrl = res.reportFileUrl.split(',');} else {this.reportFileUrl = [res.reportFileUrl];}}if (res.yxCorrectFileUrl) {if (res.yxCorrectFileUrl.indexOf(',') > -1) {this.yxReportFileUrl = res.yxCorrectFileUrl.split(',');} else {this.yxReportFileUrl = [res.yxCorrectFileUrl];}} else if (res.yxReportFileUrl) {if (res.yxReportFileUrl.indexOf(',') > -1) {this.yxReportFileUrl = res.yxReportFileUrl.split(',');} else {this.yxReportFileUrl = [res.yxReportFileUrl];}}// 给this.yxReportFileUrl和this.reportFileUrl添加字段yx和re区分this.yxReportFileUrl = this.yxReportFileUrl.map((item) => {return { url: item, type: 'yx' };});this.reportFileUrl = this.reportFileUrl.map((item) => {return { url: item, type: 're' };});this.imgs.push(...this.yxReportFileUrl);this.imgs.push(...this.reportFileUrl);this.imgsIndex = 0;console.log(99);//初始化canvasthis.initCanvas();setTimeout(() => {this.fabricObjAddEvent();}, 500);});},goBack() {console.log('返回成绩列表');this.$emit('back', 2);console.log('返回成绩列表');}}};
</script>
遇到的问题,线上链接的图片跨域了
解决办法,设置图片的时候处理跨域
setBackgroundImg(imgUrl) {this.currentImg.src = imgUrl;// 重新更新获取最新imgUrl的高度let imgss = new Image();imgss.src = imgUrl;imgss.onload = function () {console.log(imgss.height, imgss.width);};// 重新更新高度setTimeout(() => {// 将图片的宽度设置为750this.fabricObj.setWidth(750);this.fabricObj.setHeight(750 * (imgss.height / imgss.width));let _this = this;_this.fabricObj.setBackgroundImage(this.currentImg.src,_this.fabricObj.renderAll.bind(_this.fabricObj),{ crossOrigin: 'anonymous' } // 处理跨域);}, 100);},