| | |
| | | <!-- 涂色连线题控件 --> |
| | | <template> |
| | | <div class="page"> |
| | | <div class="main"> |
| | |
| | | <canvas |
| | | id="canvas" |
| | | :style="{ |
| | | backgroundImage: `url(${backgroundImage})`, |
| | | backgroundSize: 'cover', |
| | | backgroundPosition: 'center', |
| | | }" |
| | |
| | | return { |
| | | canvas: null, |
| | | context: null, |
| | | painting: false, |
| | | painting: false, // 记录状态,鼠标是否在按下状态 |
| | | historyData: [], // 存储历史数据,用于撤销 |
| | | brushSize: 5, // 笔刷大小 |
| | | brushColor: "#000000", // 笔刷颜色 |
| | |
| | | this.backgroundImage = oldData |
| | | } |
| | | }, |
| | | // watch:{ |
| | | // backgroundImage:{ |
| | | // handler(newValue) { |
| | | // if(newValue && this.context) { |
| | | // const imgData = new Image(); |
| | | // // 分两种情况,初次的图片 直接用外部链接,需要加跨域和时间戳,二次保存的作为背景则不需要 |
| | | // const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page) |
| | | // if(oldData) { |
| | | // imgData.src = newValue |
| | | // } else { |
| | | // imgData.src = newValue + '?' + new Date().getTime(); |
| | | // imgData.setAttribute('crossOrigin', ''); |
| | | // } |
| | | // imgData.onload = () => { |
| | | // this.context.drawImage(imgData,0,0) |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // }, |
| | | methods: { |
| | | changeBackground(imgUrl) { |
| | | this.backgroundImage = imgUrl; |
| | | }, |
| | | // 初始化 画布,设置大小背景色 |
| | | initCanvas() { |
| | | const that = this |
| | | function resetCanvas() { |
| | | const resetCanvas = () => { |
| | | const elPanel = document.getElementById("canvas_panel"); |
| | | that.canvas.width = elPanel.clientWidth; |
| | | that.canvas.height = elPanel.clientHeight; |
| | |
| | | that.context.fillRect(0, 0, that.canvas.width, that.canvas.height); |
| | | that.context.fillStyle = "black"; |
| | | that.getCanvasOffset(); // 更新画布位置 |
| | | // 设置画布背景图 |
| | | const imgData = new Image(); |
| | | // 分两种情况,初次的图片 直接用外部链接,需要加跨域和时间戳,二次保存的作为背景则不需要 |
| | | const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page) |
| | | if(oldData) { |
| | | imgData.src = oldData |
| | | } else { |
| | | imgData.src = this.backgroundImage + '?' + new Date().getTime(); |
| | | imgData.setAttribute('crossOrigin', ''); |
| | | } |
| | | |
| | | imgData.onload = () => { |
| | | this.context.drawImage(imgData,0,0) |
| | | } |
| | | } |
| | | resetCanvas(); |
| | | // 监听窗口大小 ,窗口改变重新渲染画布 |
| | | window.addEventListener("resize", resetCanvas); |
| | | }, |
| | | |
| | |
| | | y: y - this.canvasOffset.top, |
| | | }; |
| | | }, |
| | | |
| | | // 鼠标抬起方法 |
| | | downCallback(event) { |
| | | // 先保存之前的数据,用于撤销时恢复(绘制前保存,不是绘制后再保存) |
| | | const data = this.context.getImageData( |
| | |
| | | this.brushTool === "eraser" ? "#FFFFFF" : this.brushColor; |
| | | this.painting = true; |
| | | }, |
| | | |
| | | // 鼠标移动方法(计算坐标并渲染轨迹) |
| | | moveCallback(event) { |
| | | if (!this.painting) { |
| | | return; |
| | |
| | | closePaint() { |
| | | this.painting = false; |
| | | }, |
| | | // 重新计算画布的偏移值 |
| | | updateCanvasOffset() { |
| | | this.getCanvasOffset(); // 重新计算画布的偏移值 |
| | | this.getCanvasOffset(); |
| | | }, |
| | | |
| | | // 改变笔刷大小 |
| | | onChangeSize(size) { |
| | | this.brushSize = size; |
| | | }, |
| | | // 改变笔刷颜色 |
| | | onChangeColor(color) { |
| | | this.brushColor = color; |
| | | }, |
| | | // 保存,清空等按钮 |
| | | onChangeTool(tool) { |
| | | this.brushTool = tool; |
| | | console.log(tool); |
| | | switch (tool) { |
| | | case "clear": |
| | | this.toolClear(); |
| | |
| | | break; |
| | | } |
| | | }, |
| | | // 清空canvas所有内容(背景图除外) |
| | | toolClear() { |
| | | this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); |
| | | this.resetToolActive(); |
| | | // 新加内容,清空后将背景图再设置上去 |
| | | const imgData = new Image(); |
| | | // 分两种情况,初次的图片 直接用外部链接,需要加跨域和时间戳,二次保存的作为背景则不需要 |
| | | const oldData = localStorage.getItem(this.config.activeBook.name + '-graffiti-' + this.page) |
| | | if(oldData) { |
| | | imgData.src = oldData |
| | | } else { |
| | | imgData.src = this.backgroundImage + '?' + new Date().getTime(); |
| | | imgData.setAttribute('crossOrigin', ''); |
| | | } |
| | | imgData.onload = () => { |
| | | this.context.drawImage(imgData,0,0) |
| | | } |
| | | }, |
| | | // 原保存方法 |
| | | // 保存画布背景和划线到本地方法 |
| | | toolSave() { |
| | | var imgData = this.canvas.toDataURL({format: 'png', quality:1, width:800,}); |
| | | localStorage.setItem(this.config.activeBook.name + '-graffiti-' + this.page,imgData) |
| | | }, |
| | | // 保存方法,保存为一张图片并下载 |
| | | // 保存为一张图片并下载的方法 |
| | | saveImgData() { |
| | | var link = document.createElement("a"); |
| | | var imgData = this.canvas.toDataURL({format: 'png', quality:1, width:20000, height:4000}); |
| | |
| | | return new Blob([u8arr], {type:mime}); |
| | | } |
| | | }, |
| | | // 返回上一步方法(撤销) |
| | | toolUndo() { |
| | | // |
| | | if (this.historyData.length <= 0) { |
| | | this.resetToolActive(); |
| | | return; |
| | | } |
| | | // 将画的上一步数据写入canvas 重新渲染 |
| | | const lastIndex = this.historyData.length - 1; |
| | | this.context.putImageData(this.historyData[lastIndex], 0, 0); |
| | | this.historyData.pop(); |