<template>
	<div class="pingpu" ref="el"><canvas ref="canvasRef"></canvas></div>
</template>

<script setup>
	import { fabric } from "fabric-with-all";
	import { ref, watch, onMounted } from "vue";
	const props = defineProps({
		list: { type: Array, default: () => [] },
	});
	const el = ref(null);
	const canvasRef = ref(null);
	const observer = ref(null);
	var canvas = null;
	onMounted(async () => {
		initCanvas();
		await setCanvasData();

		let throttleTimeout = null;
		let lastRunTime = 0;
		let trailingTimeout = null;
		observer.value = new ResizeObserver((entries) => {
			const now = Date.now();
			const throttleDelay = 100;
			if (!throttleTimeout) {
				updateCanvasSize();
				lastRunTime = now;
				throttleTimeout = setTimeout(() => {
					throttleTimeout = null;
				}, throttleDelay);
			} else {
				clearTimeout(trailingTimeout);
				trailingTimeout = setTimeout(() => {
					updateCanvasSize();
					lastRunTime = Date.now();
				}, throttleDelay);
			}
		});
		observer.value.observe(el.value);
	});
	onBeforeUnmount(() => {
		observer.value.disconnect();
	});
	const initCanvas = () => {
		canvas = new fabric.Canvas(canvasRef.value, {
			selection: false,
		});
		canvas.setWidth(el.value.offsetWidth);
		canvas.setHeight(el.value.offsetHeight);
	};
	const updateCanvasSize = async () => {
		canvas.setWidth(el.value.offsetWidth);
		canvas.setHeight(el.value.offsetHeight);
		await setCanvasData();
	};
	const urlToCanvas = (url) => {
		return new Promise((resolve, reject) => {
			fabric.Image.fromURL(
				url,
				(object) => {
					const imgElement = object.getElement();
					// 创建透明 Canvas
					const tcanvas = document.createElement("canvas");
					tcanvas.width = imgElement.width;
					tcanvas.height = imgElement.height;
					const ctx = tcanvas.getContext("2d");
					ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
					ctx.drawImage(imgElement, 0, 0);
					resolve(tcanvas);
				},
				{ crossOrigin: "anonymous" }
			);
		});
	};
	const setCanvasData = async () => {
		canvas.clear();
		const cwidth = canvas.width;
		const cheight = canvas.height;

		for (let i = 0; i < props.list.length; i++) {
			let item = props.list[i];
			let image = await urlToCanvas(item.path);
			let offsetX = item.location[0];
			let offsetY = item.location[1];
			let scaleX = ((cwidth / image.width) * item.scale[0]) / 5;
			let scaleY = ((cheight / image.height) * item.scale[1]) / 5;
			let scale = cwidth > cheight ? scaleX : scaleY;
			let angle = item.angle;
			let gapX = item.object.gapX;
			let gapY = item.object.gapY;
			let patternTransform = fabric.util.composeMatrix({
				scaleX: scale,
				scaleY: scale,
				angle: angle,
			});
			// 创建透明 Canvas
			let tcanvas = document.createElement("canvas");
			tcanvas.width = image.width + gapX;
			tcanvas.height = image.height + gapY;
			let ctx = tcanvas.getContext("2d");
			ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
			ctx.drawImage(image, 0, 0);
			let pattern = new fabric.Pattern({
				source: tcanvas,
				repeat: "repeat",
				patternTransform,
				offsetX, // 水平偏移
				offsetY, // 垂直偏移
			});
			let rect = new fabric.Rect({
				id: item.id,
				width: cwidth,
				height: cheight,
				fill: pattern,

				...item.object,
			});
			canvas.add(rect);
		}
		canvas.renderAll();
	};
	const updataList = (list) => {
		
		console.log(list);
	};
	defineExpose({
		updataList,
	});
</script>

<style lang='less' scoped>
	.pingpu {
		width: 100%;
		height: 100%;
	}
</style>