From c8d1e1ed1d5c8d20a9aad8554d51001afb3c6312 Mon Sep 17 00:00:00 2001 From: YM <479443481@qq.com> Date: 星期三, 20 十一月 2024 15:28:27 +0800 Subject: [PATCH] Merge branch 'master' of http://182.92.203.7:2001/r/TextbookReader --- src/components/graffiti/index.vue | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 243 insertions(+), 0 deletions(-) diff --git a/src/components/graffiti/index.vue b/src/components/graffiti/index.vue new file mode 100644 index 0000000..4c8034a --- /dev/null +++ b/src/components/graffiti/index.vue @@ -0,0 +1,243 @@ +<!-- 娑傝壊杩炵嚎棰樻帶浠� --> +<template> + <div class="page"> + <div class="main"> + <div id="canvas_panel"> + <canvas id="canvas" :style="{ + backgroundSize: 'cover', + backgroundPosition: 'center', + }">褰撳墠娴忚鍣ㄤ笉鏀寔canvas銆�</canvas> + </div> + </div> + <div class="footer"> + <BrushSize :size="brushSize" @change-size="onChangeSize" @change-color="onChangeColor" /> + <ToolBtns :tool="brushTool" @change-tool="onChangeTool" /> + </div> + </div> +</template> + +<script> + import BrushSize from "./components/brushSize.vue"; + import ToolBtns from "./components/toolBtns.vue"; + export default { + name: "graffiti", + components: { BrushSize, ToolBtns }, + props: { + save: { + type: Function, + }, + }, + data() { + return { + canvas: null, + context: null, + painting: false, // 璁板綍鐘舵�侊紝榧犳爣鏄惁鍦ㄦ寜涓嬬姸鎬� + historyData: [], // 瀛樺偍鍘嗗彶鏁版嵁锛岀敤浜庢挙閿� + brushSize: 2, // 绗斿埛澶у皬 + brushColor: "#000000", // 绗斿埛棰滆壊 + brushTool: "brush", + canvasOffset: { + left: 0, + top: 0, + }, + }; + }, + mounted() { + this.canvas = (this.container ? this.container : document).getElementById( + "canvas" + ); + if (this.canvas.getContext) { + this.context = this.canvas.getContext("2d", { willReadFrequently: true }); + // window.addEventListener('resize', updateCanvasPosition); + (this.container ? this.container : document).addEventListener( + "scroll", + this.updateCanvasOffset, + true + ); // 娣诲姞婊氬姩鏉℃粴鍔ㄤ簨浠剁洃鍚櫒 + this.getCanvasOffset(); + this.context.lineGap = "round"; + this.context.lineJoin = "round"; + this.canvas.addEventListener("mousedown", this.downCallback); + this.canvas.addEventListener("mousemove", this.moveCallback); + this.canvas.addEventListener("mouseup", this.closePaint); + this.canvas.addEventListener("mouseleave", this.closePaint); + setTimeout(() => { + this.initCanvas(); + }, 300); + } + this.toolClear(); + }, + methods: { + // 鍒濆鍖� 鐢诲竷锛岃缃ぇ灏忚儗鏅壊 + initCanvas() { + const that = this; + const resetCanvas = () => { + const elPanel = ( + this.container ? this.container : document + ).getElementById("canvas_panel"); + console.log("clientWidth"+elPanel.clientWidth); + console.log("clientWidth"+elPanel.clientHeight); + try { + that.canvas.width = elPanel.clientWidth; + that.canvas.height = elPanel.clientHeight; + } catch (error) { } + + that.context = that.canvas.getContext("2d", { + willReadFrequently: true, + }); // 娣诲姞杩欎竴琛� + that.context.fillStyle = "white"; + that.context.fillRect(0, 0, that.canvas.width, that.canvas.height); + that.context.fillStyle = "black"; + that.getCanvasOffset(); // 鏇存柊鐢诲竷浣嶇疆 + }; + resetCanvas(); + // 鐩戝惉绐楀彛澶у皬 锛岀獥鍙f敼鍙橀噸鏂版覆鏌撶敾甯� + window.addEventListener("resize", resetCanvas); + }, + + // 鑾峰彇canvas鐨勫亸绉诲�� + getCanvasOffset() { + const rect = this.canvas.getBoundingClientRect(); + this.canvasOffset.left = rect.left * (this.canvas.width / rect.width); // 鍏煎缂╂斁鍦烘櫙 + this.canvasOffset.top = rect.top * (this.canvas.height / rect.height); + }, + + // 璁$畻褰撳墠榧犳爣鐩稿浜巆anvas鐨勫潗鏍� + calcRelativeCoordinate(x, y) { + return { + x: x - this.canvasOffset.left, + y: y - this.canvasOffset.top, + }; + }, + // 榧犳爣鎶捣鏂规硶 + downCallback(event) { + // 鍏堜繚瀛樹箣鍓嶇殑鏁版嵁锛岀敤浜庢挙閿�鏃舵仮澶嶏紙缁樺埗鍓嶄繚瀛橈紝涓嶆槸缁樺埗鍚庡啀淇濆瓨锛� + const data = this.context.getImageData( + 0, + 0, + this.canvas.width, + this.canvas.height + ); + this.saveData(data); + const { clientX, clientY } = event; + const { x, y } = this.calcRelativeCoordinate(clientX, clientY); + this.context.beginPath(); + this.context.moveTo(x, y); + this.context.lineWidth = this.brushSize; + this.context.strokeStyle = + this.brushTool === "eraser" ? "#FFFFFF" : this.brushColor; + this.painting = true; + }, + // 榧犳爣绉诲姩鏂规硶(璁$畻鍧愭爣骞舵覆鏌撹建杩�) + moveCallback(event) { + if (!this.painting) { + return; + } + const { clientX, clientY } = event; + const { x, y } = this.calcRelativeCoordinate(clientX, clientY); + this.context.lineTo(x, y); + this.context.stroke(); + }, + closePaint() { + this.painting = false; + }, + // 閲嶆柊璁$畻鐢诲竷鐨勫亸绉诲�� + updateCanvasOffset() { + this.getCanvasOffset(); + }, + // 鏀瑰彉绗斿埛澶у皬 + onChangeSize(size) { + this.brushSize = size; + }, + // 鏀瑰彉绗斿埛棰滆壊 + onChangeColor(color) { + this.brushColor = color; + }, + // 淇濆瓨锛屾竻绌虹瓑鎸夐挳 + onChangeTool(tool) { + this.brushTool = tool; + switch (tool) { + case "clear": + this.toolClear(); + break; + case "undo": + this.toolUndo(); + break; + case "save": + this.toolSave(); + break; + } + }, + // 娓呯┖canvas鎵�鏈夊唴瀹�(鑳屾櫙鍥鹃櫎澶�) + toolClear() { + this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); + this.resetToolActive(); + }, + // 淇濆瓨鐢诲竷鑳屾櫙鍜屽垝绾垮埌鏈湴鏂规硶 + toolSave() { + var imgData = this.canvas.toDataURL('image/jpeg'); + console.log(imgData); + if (this.save) { + this.save(imgData); + } + }, + // 杩斿洖涓婁竴姝ユ柟娉�(鎾ら攢) + toolUndo() { + if (this.historyData.length <= 0) { + this.resetToolActive(); + return; + } + // 灏嗙敾鐨勪笂涓�姝ユ暟鎹啓鍏anvas 閲嶆柊娓叉煋 + const lastIndex = this.historyData.length - 1; + this.context.putImageData(this.historyData[lastIndex], 0, 0); + this.historyData.pop(); + this.resetToolActive(); + }, + // 瀛樺偍鏁版嵁 + saveData(data) { + this.historyData.length >= 50 && this.historyData.shift(); // 璁剧疆鍌ㄥ瓨涓婇檺涓�50姝� + this.historyData.push(data); + }, + // 娓呴櫎銆佹挙閿�銆佷繚瀛樼姸鎬佷笉闇�瑕佷繚鎸侊紝鎿嶄綔瀹屽悗鎭㈠绗斿埛鐘舵�� + resetToolActive() { + setTimeout(() => { + this.brushTool = "brush"; + }, 1000); + }, + }, + }; +</script> + +<style scoped> + .page { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + } + + .main { + flex: 1; + } + + .footer { + display: flex; + justify-content: space-around; + align-items: center; + height: 88px; + } + + #canvas_panel { + width: 100%; + height: 100%; + margin-bottom: 12px; + /* 娑堥櫎绌烘牸褰卞搷 */ + font-size: 0; + background-color: #fff; + border-bottom: 1px solid #ccc; + } + + #canvas { + cursor: crosshair; + } +</style> \ No newline at end of file -- Gitblit v1.9.1