From f77e02b69e4512f00251929b14888f3e6bbac37f Mon Sep 17 00:00:00 2001 From: zhongshujie <2862698242@qq.com> Date: 星期一, 09 九月 2024 10:41:19 +0800 Subject: [PATCH] 艺术戏剧(bug解决) --- src/components/paint/index.vue | 387 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 360 insertions(+), 27 deletions(-) diff --git a/src/components/paint/index.vue b/src/components/paint/index.vue index 7431ddd..11f9075 100644 --- a/src/components/paint/index.vue +++ b/src/components/paint/index.vue @@ -1,44 +1,377 @@ <template> - <div class="paint" > - <canvas - width="400" - height="600" - id="canvas" - ></canvas> - <div class="paint-btn"> - <button @click="clearCanvas" >娓呴櫎</button> - </div> + <div class="paint"> + <canvas width="600" height="800" id="canvas"></canvas> + <!-- 鎿嶄綔鎸夐挳 --> + <ul class="paint-btn"> + <li class="btn-box"> + <button @click="changeDrawMode"> + {{ isDraw ? "妗嗛�夋ā寮�" : "缁樺浘妯″紡" }} + </button> + <button @click="clearCanvas">娓呴櫎</button> + <button @click="setModelEraser"> + {{ isEraser ? "鐢荤瑪" : "姗$毊鎿�" }} + </button> + <button @click="saveImgData">淇濆瓨</button> + </li> + <li> + + </li> + <li> + <label>鐢荤瑪锛�</label> + <select name="" id="" @change="changeBrush" v-model="brush"> + <option + v-for="(item, index) in modelList" + :value="item.value" + :key="index" + > + {{ item.name }} + </option> + </select> + </li> + <li> + <label>绾胯壊锛�</label> + <input type="color" v-model="lineColor" @input="changeLineColor" /> + </li> + <li> + <label>绾垮锛�</label> + <input type="range" v-model="lineWidth" @input="changeLineWidth" /> + </li> + <li> + <label>闃村奖鑹诧細</label> + <input type="color" v-model="showColor" @input="changeShowColor" /> + </li> + <li> + <label>闃村奖瀹藉害锛�</label> + <input type="range" v-model="showWidth" @input="changeShowWidth" /> + </li> + <li> + <label>闃村奖鍋忕Щ閲忥細</label> + <input type="range" v-model="showOffset" @input="changeShowOffset" /> + </li> + </ul> </div> </template> <script> import { fabric } from "fabric-with-erasing"; - export default { - data() { - return { +export default { + data() { + return { + backgroundImgUrl: "", // 鑳屾櫙 + isDraw: true, // 缁樼敾銆佹閫夋ā寮� + brush: "Pencil", // 鐢荤瑪绫诲瀷 + lineColor: "#000", + lineWidth: 1, + isEraser: false, + showColor: "#000", // 闃村奖鑹� + showWidth: 0, // 闃村奖瀹藉害 + showOffset: 0, + modelList: [ + { + name: "Pencil", + value: "Pencil", + }, + { + name: "Circle", + value: "Circle", + }, + { + name: "Spray", + value: "Spray", + }, + { + name: "Pattern", + value: "Pattern", + }, + { + name: "hline", + value: "hline", + }, + { + name: "vline", + value: "vline", + }, + { + name: "square", + value: "square", + }, + { + name: "diamond", + value: "diamond", + }, + { + name: "texture", + value: "texture", + }, + ], + // 鐢荤瑪妯″紡 + vLinePatternBrush: null, + hLinePatternBrush: null, + squarePatternBrush: null, + diamondPatternBrush: null, + texturePatternBrush: null, + }; + }, + props: { + imgUrl: { + type: String, + default: + "https://cdn.learnku.com/uploads/images/202206/29/97252/aArKOJpl2A.png!large", + }, + page: { + type: Number, + default: 1, + }, + }, + mounted() { + this.init(); + }, + methods: { + // 鍒濆鍖栫敾甯� + init() { + this.canvas = new fabric.Canvas("canvas", { + isDrawingMode: true, + }); + // 璁剧疆鑳屾櫙 + this.setBackgroundImage() + // + fabric.Object.prototype.transparentCorners = false; + this.setBrush() + }, + // 鍒涘缓鍚勭绗斿埛 + setBrush() { + if (fabric.PatternBrush) { + // 鐢荤瑪鏍峰紡 + this.vLinePatternBrush = new fabric.PatternBrush(this.canvas); + this.vLinePatternBrush.getPatternSrc = () => { + let patternCanvas = fabric.document.createElement("canvas"); + patternCanvas.width = patternCanvas.height = 10; + let ctx = patternCanvas.getContext("2d"); + ctx.strokeStyle = this.lineColor; + ctx.lineWidth = 5; + ctx.beginPath(); + ctx.moveTo(0, 5); + ctx.lineTo(10, 5); + ctx.closePath(); + ctx.stroke(); + return patternCanvas; + }; + this.hLinePatternBrush = new fabric.PatternBrush(this.canvas); + this.hLinePatternBrush.getPatternSrc = function () { + let patternCanvas = fabric.document.createElement("canvas"); + patternCanvas.width = patternCanvas.height = 10; + let ctx = patternCanvas.getContext("2d"); + ctx.strokeStyle = this.lineColor; + ctx.lineWidth = 5; + ctx.beginPath(); + ctx.moveTo(5, 0); + ctx.lineTo(5, 10); + ctx.closePath(); + ctx.stroke(); + return patternCanvas; + }; + this.squarePatternBrush = new fabric.PatternBrush(this.canvas); + this.squarePatternBrush.getPatternSrc = function () { + const squareWidth = 10; + const squareDistance = 2; + const patternCanvas = fabric.document.createElement("canvas"); + patternCanvas.width = patternCanvas.height = + squareWidth + squareDistance; + const ctx = patternCanvas.getContext("2d"); + ctx.fillStyle = this.color; + ctx.fillRect(0, 0, squareWidth, squareWidth); + return patternCanvas; + }; + this.diamondPatternBrush = new fabric.PatternBrush(this.canvas); + this.diamondPatternBrush.getPatternSrc = function () { + const squareWidth = 10; + const squareDistance = 5; + const patternCanvas = fabric.document.createElement("canvas"); + const rect = new fabric.Rect({ + width: squareWidth, + height: squareWidth, + angle: 45, + fill: this.color, + }); + var canvasWidth = rect.getBoundingRect().width; + patternCanvas.width = patternCanvas.height = + canvasWidth + squareDistance; + rect.set({ left: canvasWidth / 2, top: canvasWidth / 2 }); + var ctx = patternCanvas.getContext("2d"); + rect.render(ctx); + return patternCanvas; + }; + const img = new Image(); + // img.src = "../assets/images/drop.jpg"; + this.texturePatternBrush = new fabric.PatternBrush(this.canvas); + this.texturePatternBrush.source = img; } }, - mounted() { - this.init() + // 璁剧疆鑳屾櫙鍥炬柟娉� + setBackgroundImage() { + // 浣跨敤fabric鐨処mage.fromURL鏂规硶鏉ュ姞杞藉浘鍍� + const oldData = localStorage.getItem( + this.config.activeBook.name + "-paint-" + this.page + ); + this.backgroundImgUrl = oldData || this.imgUrl; + fabric.Image.fromURL( + this.backgroundImgUrl, + (img) => { + // 鍥惧儚鍔犺浇瀹屾垚鍚庯紝灏嗗叾璁剧疆涓虹敾甯冪殑鑳屾櫙 + img + .scale( + this.canvas.width / img.width, + this.canvas.height / img.height + ) + .set({ + left: 0, + top: 0, + originX: "left", + originY: "top", + }); + + // 灏嗗浘鍍忔坊鍔犲埌鐢诲竷涓紝骞跺皢鍏舵斁鍦ㄦ渶搴曞眰 + this.canvas.setBackgroundImage( + img, + this.canvas.renderAll.bind(this.canvas), + { + // 鍙互璁剧疆鍥惧儚鐨勬牱寮忥紝姣斿涓嶉�忔槑搴� + opacity: 0.5, + } + ); + // 娓叉煋鐢诲竷 + this.canvas.renderAll(); + }, + { + crossOrigin: "Anonymous", // 濡傛灉鍥惧儚鍦ㄤ笉鍚屽煙涓婏紝闇�瑕佽缃甤rossOrigin + } + ); }, - methods: { - // 鍒濆鍖栫敾甯� - init() { - this.canvas = new fabric.Canvas("canvas",{ - isDrawingMode: true + // 缁樺浘 妗嗛�� 妯″紡鍒囨崲 + changeDrawMode() { + this.isDraw = !this.isDraw; + this.canvas.isDrawingMode = !this.canvas.isDrawingMode; + }, + // 娓呯┖鐢诲竷 + clearCanvas() { + this.canvas.clear(); + this.setBackgroundImage() + }, + // 淇敼鐢荤瑪棰滆壊 + changeLineColor(e) { + let brush = this.canvas.freeDrawingBrush; + brush.color = e.srcElement.value; + if (brush.getPatternSrc) { + brush.source = brush.getPatternSrc.call(brush); + } + console.log(e.srcElement.value); + }, + // 淇敼鐢荤瑪绮楃粏 + changeLineWidth(e) { + console.log(e); + this.canvas.freeDrawingBrush.width = + parseInt(e.srcElement.value, 10) || 1; + }, + // 鐢荤瑪鏍峰紡鍒囨崲 + changeBrush() { + if (this.brush == "hline") { + this.canvas.freeDrawingBrush = this.vLinePatternBrush; + } else if (this.brush == "vline") { + this.canvas.freeDrawingBrush = this.hLinePatternBrush; + } else if (this.brush == "square") { + this.canvas.freeDrawingBrush = this.squarePatternBrush; + } else if (this.brush == "diamond") { + this.canvas.freeDrawingBrush = this.diamondPatternBrush; + } else if (this.brush == "texture") { + this.canvas.freeDrawingBrush = this.texturePatternBrush; + } else { + this.canvas.freeDrawingBrush = new fabric[this.brush + "Brush"]( + this.canvas + ); + } + if (this.canvas.freeDrawingBrush) { + var brush = this.canvas.freeDrawingBrush; + brush.color = this.lineColor; + if (brush.getPatternSrc) { + brush.source = brush.getPatternSrc.call(brush); + } + brush.width = parseInt(this.lineWidth, 10) || 1; + brush.shadow = new fabric.Shadow({ + blur: parseInt(this.showWidth, 10) || 0, + offsetX: 0, + offsetY: 0, + affectStroke: true, + color: this.showColor, }); - }, - // 娓呯┖鐢诲竷 - clearCanvas() { - this.canvas.clear() } }, - } + // 姗$毊鎿� + setModelEraser() { + this.isEraser = !this.isEraser; + if (this.isEraser) { + this.canvas.freeDrawingBrush = new fabric.EraserBrush(this.canvas); // 浣跨敤姗$毊鎿︾敾绗� + this.canvas.freeDrawingBrush.width = this.lineWidth; + } else { + this.changeBrush(); + // this.canvas.freeDrawingBrush = new fabric.PencilBrush(this.canvas); // 浣跨敤姗$毊鎿︾敾绗� + // this.canvas.freeDrawingBrush.width = this.lineWidth; // 璁剧疆鐢荤瑪绮楃粏 + } + }, + // 淇敼闃村奖鑹� + changeShowColor(e) { + this.canvas.contextContainer.shadowColor = e.srcElement.value; + }, + + // 闃村奖瀹藉害 + changeShowWidth(e) { + console.log(this.canvas); + this.canvas.contextContainer.shadowBlur = + parseInt(e.srcElement.value, 10) || 0; + }, + // 闃村奖鍋忕Щ閲� + changeShowOffset(e) { + this.canvas.contextContainer.shadowOffsetX = + parseInt(e.srcElement.value, 10) || 0; + this.canvas.contextContainer.shadowOffsetY = + parseInt(e.srcElement.value, 10) || 0; + }, + // 淇濆瓨鍥句功 + saveImgData() { + const imgData = this.canvas.toDataURL({ + format: "png", // 鎸囧畾杈撳嚭鏍煎紡锛岄�氬父鏄�'png'鎴�'jpeg' + quality: 0.8, // 浠呭湪杈撳嚭鏍煎紡涓�'jpeg'鏃舵湁鏁� + multiplier: 1, // 鎻愰珮鍒嗚鲸鐜囷紝鍙�夊弬鏁帮紝榛樿涓�1 + left: 0, // 瑁佸壀鍖哄煙鐨勫乏杈圭晫锛堝彲閫夛級 + top: 0, // 瑁佸壀鍖哄煙鐨勪笂杈圭晫锛堝彲閫夛級 + width: canvas.width, // 瑁佸壀鍖哄煙鐨勫搴︼紙鍙�夛紝榛樿涓虹敾甯冪殑瀹藉害锛� + height: canvas.height, // 瑁佸壀鍖哄煙鐨勯珮搴︼紙鍙�夛紝榛樿涓虹敾甯冪殑楂樺害锛� + }); + localStorage.setItem( + this.config.activeBook.name + "-paint-" + this.page, + imgData + ); + console.log("鏈湴鍥�", imgData); + }, + }, +}; </script> <style lang="less" scoped> - #canvas { - border: 1px solid #ccc +#canvas { + border: 1px solid #ccc; +} +.paint-btn { + margin-top:40px; + padding:20px; + border:1px solid #ededed; + width:max-content; + li { + margin-bottom:6px; } -</style> \ No newline at end of file +} +.btn-box { + display:flex; + justify-content:space-between; +} +</style> -- Gitblit v1.9.1