|
@@ -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));
|
|
|
}
|