事件替换颜色等画布

This commit is contained in:
李志鹏
2026-01-09 14:40:18 +08:00
parent 274ea15dcc
commit 88bd58fc66
8 changed files with 584 additions and 200 deletions

View File

@@ -1,121 +1,201 @@
<template>
<div class="test">
<div v-for="(item, index) in data" :key="index">
<div class="control">
<div>
<span>偏移X</span>
<input type="number" v-model="item.offsetX" />
</div>
<div>
<span>偏移Y</span>
<input type="number" v-model="item.offsetY" />
</div>
<div>
<span>角度</span>
<input type="number" v-model="item.angle" />
</div>
<div>
<span>缩放</span>
<input type="number" v-model="item.scale" />
</div>
<div>
<span>水平间距</span>
<input type="number" v-model="item.gapX" />
</div>
<div>
<span>垂直间距</span>
<input type="number" v-model="item.gapY" />
</div>
<h2>---------整体--------</h2>
<div>
<span>缩放</span>
<input type="number" v-model="item.object.scale" step="0.1" />
</div>
<div>
<span>X</span>
<input type="number" v-model="item.object.left" />
</div>
<div>
<span>Y</span>
<input type="number" v-model="item.object.top" />
</div>
<div class="control" v-for="(item, index) in list" :key="index">
<div>
<span>偏移X</span>
<input type="number" v-model="item.location[0]" />
</div>
<div class="box">
<pingpu v-bind="item" :style="{
transform: `translate(${item.object.left}px, ${item.object.top}px) scale(${item.object.scale})`,
transformOrigin: 'top left'
}" />
<div>
<span>偏移Y</span>
<input type="number" v-model="item.location[1]" />
</div>
<div>
<span>角度</span>
<input type="number" v-model="item.angle" />
</div>
<div>
<span>缩放</span>
<input type="number" v-model="item.scale" />
</div>
<div>
<span>水平间距</span>
<input type="number" v-model="item.object.gapX" />
</div>
<div>
<span>垂直间距</span>
<input type="number" v-model="item.object.gapY" />
</div>
<hr />
<div>
<span>缩放X</span>
<input type="number" v-model="item.object.scaleX" step="0.1" />
</div>
<div>
<span>缩放Y</span>
<input type="number" v-model="item.object.scaleY" step="0.1" />
</div>
<div>
<span>X</span>
<input type="number" v-model="item.object.left" />
</div>
<div>
<span>Y</span>
<input type="number" v-model="item.object.top" />
</div>
<div>
<span>透明度</span>
<input
type="range"
v-model="item.object.opacity"
step="0.1"
min="0"
max="1"
/>
</div>
</div>
<div class="box">
<pingpu :list="list" ref="pingpuRef" />
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch } from "vue";
import pingpu from "./pingpu.vue";
const data = ref([
{
url: "/src/assets/images/canvas/yinhua1.jpg",
offsetX: 0, // px
offsetY: 0, // px
angle: 0, // 角度
scale: 100, // %
gapX: 0, // px
gapY: 0, // px
const convertDotNotationToBracket = (str) =>
str.replace(/(?:^|\.)(\d+)(?=\.|$)/g, "[#$1]").replace(/\[#/g, "[");
object:{
scale: 1, // %
top: 0, // px
left: 0, // px
}
const list = ref([
{
id: "1",
ifSingle: false,
level2Type: "Pattern",
designType: "Library",
path: "/src/assets/images/canvas/yinhua1.jpg",
location: [0, 0],
scale: [1, 1],
angle: 0,
name: "Print2",
priority: 1,
object: {
top: 0,
left: 0,
scaleX: 1,
scaleY: 1,
opacity: 1,
angle: 0,
flipX: false,
flipY: false,
blendMode: "multiply",
gapX: 10,
gapY: 20,
},
},
{
url: "/src/assets/images/canvas/yinhua1.jpg",
offsetX: 0, // px
offsetY: 0, // px
angle: 0, // 角度
scale: 100, // %
gapX: 0, // px
gapY: 0, // px
object:{
scale: 1, // %
top: 0, // px
left: 0, // px
}
id: "2",
ifSingle: false,
level2Type: "Pattern",
designType: "Library",
path: "/src/assets/images/canvas/yinhua1.jpg",
location: [0, 0],
scale: [2, 2],
angle: -45,
name: "Print2",
priority: 1,
object: {
top: 150,
left: 250,
scaleX: 0.5,
scaleY: 0.5,
opacity: 1,
angle: 45,
flipX: false,
flipY: false,
blendMode: "multiply",
gapX: 0,
gapY: 0,
},
},
]);
// 深拷贝
const deepCopy = (obj) => JSON.parse(JSON.stringify(obj));
const oldList = ref(deepCopy(list.value));
const pingpuRef = ref(null);
watch(
() => list.value,
() => updateList(),
{ deep: true }
);
const updateList = () => {
const changeList = [];
oldList.value.forEach((oldItem) => {
const newItem = list.value.find((v) => v.id === oldItem.id);
if (newItem) {
const arr = findDiffProps(oldItem, newItem);
arr.forEach((item) => {
changeList.push({
...item,
id: oldItem.id,
action: "update-item",
key: convertDotNotationToBracket(item.key),
});
});
} else {
changeList.push({
id: oldItem.id,
action: "delete-item",
});
}
});
oldList.value = deepCopy(list.value);
console.log(changeList);
if (changeList.length) {
pingpuRef.value.updataList(changeList);
}
};
// 递归查找不同的属性
const findDiffProps = (obj1, obj2, diffProps = [], path = "") => {
for (const key in obj1) {
if (typeof obj1[key] === "object") {
findDiffProps(obj1[key], obj2[key], diffProps, `${path}${key}.`);
} else if (obj1[key] !== obj2[key]) {
diffProps.push({
key: `${path}${key}`,
oldValue: obj1[key],
newValue: obj2[key],
});
}
}
return diffProps;
};
</script>
<style lang='less' scoped>
.test {
display: flex;
> div {
width: 50%;
> .control {
margin-left: 10px;
margin-top: 10px;
> div {
display: flex;
align-items: center;
margin-bottom: 5px;
> span {
width: 80px;
}
> input {
padding-left: 10px;
border-radius: 5px;
}
> .control {
display: inline-block;
border: 1px solid #000;
padding: 10px;
margin: 10px;
border-radius: 10px;
> div {
display: flex;
align-items: center;
margin-bottom: 5px;
> span {
width: 80px;
}
> input {
padding-left: 10px;
border-radius: 5px;
}
}
> .box {
position: fixed;
top: 40%;
left: 10%;
width: 300px;
height: 500px;
overflow: hidden;
border: 1px solid #000;
}
}
> .box {
width: 400px;
height: 500px;
overflow: hidden;
border: 1px solid #000;
}
}
</style>