lxf hai 1 ano
pai
achega
1337099539
Modificáronse 1 ficheiros con 141 adicións e 61 borrados
  1. 141 61
      src/views/group/picLibrary/demo/index.vue

+ 141 - 61
src/views/group/picLibrary/demo/index.vue

@@ -1,5 +1,10 @@
 <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>
+    </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>
     </div>
@@ -7,6 +12,8 @@
 </template>
 
 <script setup>
+import { ElMessage } from "element-plus";
+
 const imgs = [
   { name: "p1", url: "/img/miao.png" },
   { name: "p2", url: "/img/miao2.png" },
@@ -19,12 +26,12 @@ const width = ref(500);
 const height = ref(500);
 /** 图片数据 名字 位置等 */
 const imagesData = ref([]);
+let clickCoordinate = { x: 0, y: 0 };
+let target = ref(undefined);
 /** 图片拖拽 */
 const init = () => {
   ctx.value = canvas.value.getContext("2d");
   /** 当前点击的信息 */
-  let clickCoordinate = { x: 0, y: 0 };
-  let target = ref("");
   imgs.forEach((item) => {
     let img = new Image();
     img.src = item.url;
@@ -35,76 +42,149 @@ const init = () => {
       const x = Math.random() * (width.value - w);
       const y = Math.random() * (height.value - h);
       const selectStatus = false;
-      const obj = { img, name, x, y, w, h, selectStatus };
+      const angle = 0;
+      const obj = { img, name, x, y, w, h, selectStatus, angle };
       imagesData.value.push(obj);
       drawByObj(obj);
     };
   });
-  function drawByObj(obj) {
-    if (obj.selectStatus) {
-      drawGuideByObj(obj);
-    }
-    ctx.value.drawImage(obj.img, obj.x, obj.y, obj.w, obj.h);
-  }
-  function drawGuideByObj(obj) {
-    ctx.value.beginPath();
-    ctx.value.lineWidth = 4;
-    ctx.value.strokeStyle = "green";
-    ctx.value.rect(obj.x, obj.y, obj.w, obj.h);
-    ctx.value.stroke();
-  }
   canvas.value.addEventListener("mousedown", mousedownFn, false);
-  function mousedownFn(e) {
-    clickCoordinate.x = e.offsetX - canvas.value.offsetLeft;
-    clickCoordinate.y = e.offsetY - canvas.value.offsetTop;
-    checkElement();
-    if (target.value == undefined) return;
-    canvas.value.addEventListener("mousemove", mousemoveFn, false);
-    canvas.value.addEventListener("mouseup", mouseupFn, false);
+};
+onMounted(() => {
+  init();
+});
+const drawByObj = (obj) => {
+  if (obj.selectStatus) {
+    drawGuideByObj(obj);
   }
-  /** 判断点击的是哪个 */
-  function checkElement() {
-    imagesData.value.forEach((item, index) => {
-      drawGuideByObj(item);
-      if (ctx.value.isPointInPath(clickCoordinate.x, clickCoordinate.y)) {
-        console.log("点击的元素是:", item.name);
-        target.value = index;
-        item.selectStatus = true;
-        return;
-      } else {
-        item.selectStatus = false;
-        // 清空画布
-        ctx.value.clearRect(0, 0, width.value, height.value);
-        // 清空画布以后重新绘制
-        imagesData.value.forEach((i) => drawByObj(i));
+  ctx.value.save(); // 保存旧的坐标系状态
+  ctx.value.translate(obj.x + obj.w / 2, obj.y + obj.h / 2); // 坐标原点移动到旋转中心
+  ctx.value.rotate((obj.angle * Math.PI) / 180); // 旋转坐标系
+  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(); // 还原之前的坐标系状态
+};
+const drawGuideByObj = (obj) => {
+  ctx.value.save(); // 保存旧的坐标系状态
+  ctx.value.beginPath();
+  ctx.value.lineWidth = 4;
+  ctx.value.strokeStyle = "green";
+  ctx.value.translate(obj.x + obj.w / 2, obj.y + obj.h / 2); // 坐标原点移动到旋转中心
+  ctx.value.rotate((obj.angle * Math.PI) / 180); // 旋转坐标系
+  ctx.value.translate(-(obj.x + obj.w / 2), -(obj.y + obj.h / 2)); // 坐标原点还原
+  ctx.value.rect(obj.x, obj.y, obj.w, obj.h); // 以新坐标系为参照,画出矩形。
+  ctx.value.stroke();
+  ctx.value.restore(); // 还原之前的坐标系状态
+};
+const mousedownFn = (e) => {
+  clickCoordinate.x = e.offsetX - canvas.value.offsetLeft;
+  clickCoordinate.y = e.offsetY - canvas.value.offsetTop;
+  checkElement();
+  if (target.value == undefined) return;
+  canvas.value.addEventListener("mousemove", mousemoveFn, false);
+  canvas.value.addEventListener("mouseup", mouseupFn, false);
+};
+/** 判断点击的是哪个 */
+const checkElement = () => {
+  imagesData.value.forEach((item, index) => {
+    drawGuideByObj(item);
+    if (ctx.value.isPointInPath(clickCoordinate.x, clickCoordinate.y)) {
+      console.log("点击的元素是:", item.name);
+      target.value = index;
+      item.selectStatus = true;
+      return;
+    } else {
+      item.selectStatus = false;
+      // 清空画布
+      ctx.value.clearRect(0, 0, width.value, height.value);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
+    }
+  });
+};
+const mousemoveFn = (e) => {
+  // 计算点击位置和图片原点位置的差
+  let sx = clickCoordinate.x - imagesData.value[target.value].x;
+  let sy = clickCoordinate.y - imagesData.value[target.value].y;
+  // 计算移动元素的坐标
+  imagesData.value[target.value].x = e.offsetX - canvas.value.offsetLeft - sx;
+  imagesData.value[target.value].y = e.offsetY - canvas.value.offsetTop - sy;
+  // 重新赋值点击位置
+  clickCoordinate.x = e.offsetX - canvas.value.offsetLeft;
+  clickCoordinate.y = e.offsetY - canvas.value.offsetTop;
+  // 清空画布
+  ctx.value.clearRect(0, 0, width.value, height.value);
+  // 清空画布以后重新绘制
+  imagesData.value.forEach((i) => drawByObj(i));
+};
+const mouseupFn = () => {
+  // 鼠标抬起以后移除事件
+  canvas.value.removeEventListener("mousemove", mousemoveFn, false);
+  canvas.value.removeEventListener("mouseup", mouseupFn, false);
+  target.value = undefined;
+};
+const clickA = () => {
+  if (imagesData.value && imagesData.value.length > 0) {
+    let status = true;
+    for (let i = 0; i < imagesData.value.length; i++) {
+      if (imagesData.value[i].selectStatus) {
+        status = false;
+        break;
       }
-    });
+    }
+    if (status) {
+      return ElMessage("请选中元素");
+    }
+  } else {
+    return ElMessage("请添加元素");
   }
-  function mousemoveFn(e) {
-    // 计算点击位置和图片原点位置的差
-    let sx = clickCoordinate.x - imagesData.value[target.value].x;
-    let sy = clickCoordinate.y - imagesData.value[target.value].y;
-    // 计算移动元素的坐标
-    imagesData.value[target.value].x = e.offsetX - canvas.value.offsetLeft - sx;
-    imagesData.value[target.value].y = e.offsetY - canvas.value.offsetTop - sy;
-    // 重新赋值点击位置
-    clickCoordinate.x = e.offsetX - canvas.value.offsetLeft;
-    clickCoordinate.y = e.offsetY - canvas.value.offsetTop;
-    // 清空画布
-    ctx.value.clearRect(0, 0, width.value, height.value);
-    // 清空画布以后重新绘制
-    imagesData.value.forEach((i) => drawByObj(i));
+};
+const clickB = () => {
+  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;
+        break;
+      }
+    }
+    if (status) {
+      return ElMessage("请选中元素");
+    } else {
+      // 清空画布
+      ctx.value.clearRect(0, 0, width.value, height.value);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
+    }
+  } else {
+    return ElMessage("请添加元素");
   }
-  function mouseupFn(e) {
-    // 鼠标抬起以后移除事件
-    canvas.value.removeEventListener("mousemove", mousemoveFn, false);
-    canvas.value.removeEventListener("mouseup", mouseupFn, false);
-    target.value = undefined;
+};
+const clickC = () => {
+  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);
+      // 清空画布以后重新绘制
+      imagesData.value.forEach((i) => drawByObj(i));
+    }
+  } else {
+    return ElMessage("请添加元素");
   }
 };
-onMounted(() => {
-  init();
-});
 </script>
 
 <style lang="scss" scoped></style>