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