<template>
	<div class="test">
		<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>
				<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 convertDotNotationToBracket = (str) =>
		str.replace(/(?:^|\.)(\d+)(?=\.|$)/g, "[#$1]").replace(/\[#/g, "[");

	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,
			},
		},
		{
			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 {
		> .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 {
			width: 400px;
			height: 500px;
			overflow: hidden;
			border: 1px solid #000;
		}
	}
</style>