Jelajahi Sumber

canvas 图片镜像 放大缩小

lxf 1 tahun lalu
induk
melakukan
aa3e8c84b3
1 mengubah file dengan 108 tambahan dan 19 penghapusan
  1. 108 19
      src/views/group/picLibrary/demo/index.vue

+ 108 - 19
src/views/group/picLibrary/demo/index.vue

@@ -1,12 +1,15 @@
 <template>
   <el-card class="box-card">
     <div>
-      <el-button type="primary" @click="clickA()">翻转</el-button>
-      <el-button type="primary" @click="clickB()">旋转45°</el-button>
-      <el-button type="primary" @click="clickC()">旋转-45°</el-button>
+      <el-button type="primary" @click="clickA()">上下翻转</el-button>
+      <el-button type="primary" @click="clickB()">左右翻转</el-button>
+      <el-button type="primary" @click="clickC()">旋转45°</el-button>
+      <el-button type="primary" @click="clickD()">旋转-45°</el-button>
+      <el-button type="primary" @click="clickE()">放大</el-button>
+      <el-button type="primary" @click="clickF()">缩小</el-button>
     </div>
     <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)">
-      <canvas ref="canvas" width="500" height="500" style="border: 1px solid #ccc"></canvas>
+      <canvas ref="canvas" :width="width" :height="height" style="border: 1px solid #ccc"></canvas>
     </div>
   </el-card>
 </template>
@@ -17,16 +20,17 @@ import { ElMessage } from "element-plus";
 const imgs = [
   { name: "p1", url: "/img/miao.png" },
   { name: "p2", url: "/img/miao2.png" },
-  // { name: "p3", url: "/img/miao3.png" },
-  { name: "p3", url: "https://os.winfaster.cn/sd/prod/2023/11/14/9481247b7e7145e7bbc38f0823a00fd5.png" },
+  { name: "p3", url: "/img/miao3.png" },
+  { name: "p4", url: "/img/miao2.png" },
+  { name: "p5", url: "https://os.winfaster.cn/sd/prod/2023/11/14/9481247b7e7145e7bbc38f0823a00fd5.png" },
 ];
 const canvas = ref(null);
+const width = ref(1000);
+const height = ref(700);
 const ctx = ref("");
-const width = ref(500);
-const height = ref(500);
 /** 图片数据 名字 位置等 */
 const imagesData = ref([]);
-let clickCoordinate = { x: 0, y: 0 };
+const clickCoordinate = { x: 0, y: 0 };
 let target = ref(undefined);
 /** 图片拖拽 */
 const init = () => {
@@ -39,11 +43,13 @@ const init = () => {
     img.onload = function () {
       const w = 100;
       const h = (w / img.width) * img.height;
-      const x = Math.random() * (width.value - w);
-      const y = Math.random() * (height.value - h);
+      const x = Math.random() * (canvas.value.width - w);
+      const y = Math.random() * (canvas.value.height - h);
       const selectStatus = false;
       const angle = 0;
-      const obj = { img, name, x, y, w, h, selectStatus, angle };
+      const upAndDown = false;
+      const leftAndRight = false;
+      const obj = { img, name, x, y, w, h, selectStatus, angle, upAndDown, leftAndRight };
       imagesData.value.push(obj);
       drawByObj(obj);
     };
@@ -60,6 +66,12 @@ const drawByObj = (obj) => {
   ctx.value.save(); // 保存旧的坐标系状态
   ctx.value.translate(obj.x + obj.w / 2, obj.y + obj.h / 2); // 坐标原点移动到旋转中心
   ctx.value.rotate((obj.angle * Math.PI) / 180); // 旋转坐标系
+  if (obj.upAndDown) {
+    ctx.value.scale(1, -1); //上下镜像翻转
+  }
+  if (obj.leftAndRight) {
+    ctx.value.scale(-1, 1); //左右镜像翻转
+  }
   ctx.value.translate(-(obj.x + obj.w / 2), -(obj.y + obj.h / 2)); // 坐标原点还原
   ctx.value.drawImage(obj.img, obj.x, obj.y, obj.w, obj.h);
   ctx.value.restore(); // 还原之前的坐标系状态
@@ -96,7 +108,7 @@ const checkElement = () => {
     } else {
       item.selectStatus = false;
       // 清空画布
-      ctx.value.clearRect(0, 0, width.value, height.value);
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
       // 清空画布以后重新绘制
       imagesData.value.forEach((i) => drawByObj(i));
     }
@@ -113,7 +125,7 @@ const mousemoveFn = (e) => {
   clickCoordinate.x = e.offsetX - canvas.value.offsetLeft;
   clickCoordinate.y = e.offsetY - canvas.value.offsetTop;
   // 清空画布
-  ctx.value.clearRect(0, 0, width.value, height.value);
+  ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
   // 清空画布以后重新绘制
   imagesData.value.forEach((i) => drawByObj(i));
 };
@@ -128,12 +140,18 @@ const clickA = () => {
     let status = true;
     for (let i = 0; i < imagesData.value.length; i++) {
       if (imagesData.value[i].selectStatus) {
+        imagesData.value[i].upAndDown = !imagesData.value[i].upAndDown;
         status = false;
         break;
       }
     }
     if (status) {
       return ElMessage("请选中元素");
+    } else {
+      // 清空画布
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
     }
   } else {
     return ElMessage("请添加元素");
@@ -144,7 +162,8 @@ const clickB = () => {
     let status = true;
     for (let i = 0; i < imagesData.value.length; i++) {
       if (imagesData.value[i].selectStatus) {
-        imagesData.value[i].angle = imagesData.value[i].angle + 45;
+        imagesData.value[i].leftAndRight = !imagesData.value[i].leftAndRight;
+        console.log(imagesData.value[i]);
         status = false;
         break;
       }
@@ -153,7 +172,7 @@ const clickB = () => {
       return ElMessage("请选中元素");
     } else {
       // 清空画布
-      ctx.value.clearRect(0, 0, width.value, height.value);
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
       // 清空画布以后重新绘制
       imagesData.value.forEach((i) => drawByObj(i));
     }
@@ -166,18 +185,88 @@ const clickC = () => {
     let status = true;
     for (let i = 0; i < imagesData.value.length; i++) {
       if (imagesData.value[i].selectStatus) {
+        imagesData.value[i].angle = imagesData.value[i].angle + 45;
+        status = false;
+        break;
+      }
+    }
+    if (status) {
+      return ElMessage("请选中元素");
+    } else {
+      // 清空画布
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
+    }
+  } else {
+    return ElMessage("请添加元素");
+  }
+};
+const clickD = () => {
+  if (imagesData.value && imagesData.value.length > 0) {
+    let status = true;
+    for (let i = 0; i < imagesData.value.length; i++) {
+      if (imagesData.value[i].selectStatus) {
         imagesData.value[i].angle = imagesData.value[i].angle - 45;
         status = false;
-        console.log(imagesData.value);
         break;
       }
     }
     if (status) {
       return ElMessage("请选中元素");
     } else {
-      console.log(imagesData.value);
       // 清空画布
-      ctx.value.clearRect(0, 0, width.value, height.value);
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
+    }
+  } else {
+    return ElMessage("请添加元素");
+  }
+};
+const clickE = () => {
+  if (imagesData.value && imagesData.value.length > 0) {
+    let status = true;
+    for (let i = 0; i < imagesData.value.length; i++) {
+      if (imagesData.value[i].selectStatus) {
+        imagesData.value[i].w = imagesData.value[i].w + 10;
+        imagesData.value[i].h = (imagesData.value[i].w / imagesData.value[i].img.width) * imagesData.value[i].img.height;
+        status = false;
+        break;
+      }
+    }
+    if (status) {
+      return ElMessage("请选中元素");
+    } else {
+      // 清空画布
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
+    }
+  } else {
+    return ElMessage("请添加元素");
+  }
+};
+const clickF = () => {
+  if (imagesData.value && imagesData.value.length > 0) {
+    let status = true;
+    for (let i = 0; i < imagesData.value.length; i++) {
+      if (imagesData.value[i].selectStatus) {
+        if (imagesData.value[i].w > 10) {
+          imagesData.value[i].w = imagesData.value[i].w - 10;
+          imagesData.value[i].h = (imagesData.value[i].w / imagesData.value[i].img.width) * imagesData.value[i].img.height;
+        } else {
+          return ElMessage("已缩小到最小");
+        }
+        status = false;
+        break;
+      }
+    }
+    if (status) {
+      return ElMessage("请选中元素");
+    } else {
+      // 清空画布
+      ctx.value.clearRect(0, 0, 2 * canvas.value.width, 2 * canvas.value.height);
       // 清空画布以后重新绘制
       imagesData.value.forEach((i) => drawByObj(i));
     }