<template>
	<div class="image-clip">
		<div class="image-clip-body" ref="imageClipBody">
			<VueCropper
				ref="cropper"
				:img="url"
				crossOrigin="Anonymous"
				:autoCrop="true"
				:fixedNumber="ratio"
				fixed
				movable
				centerBox
				@realTime="onChange"
			></VueCropper>
		</div>
		<div class="clip_opterate">
			<div class="item" @click="rotateLeft()">
				<span class="icon iconfont icon-chexiao operate_icon"></span>
			</div>
			<div class="item" @click="rotateRight()">
				<span class="icon iconfont icon-chexiao operate_icon icon_chexiao_sec"></span>
			</div>
			<div class="item" @click="changeScale(-0.1)">
				<span class="operate_icon icon_font">-</span>
			</div>
			<div class="item" @click="changeScale(0.1)">
				<span class="operate_icon icon_font">+</span>
			</div>
			<div class="item" @click="refreshCrop()">
				<span class="icon iconfont icon-shuaxin operate_icon"></span>
			</div>
		</div>
	</div>
</template>
<script setup>
	import { ref, useAttrs, onMounted, onBeforeUnmount } from "vue"
	import "vue-cropper/dist/index.css"
	import { VueCropper } from "vue-cropper"
	const props = defineProps({
		url: {
			type: String,
			default: ""
		},
		ratio: {
			type: Array,
			default: () => [1, 1]
		}
	})
	const attrs = useAttrs()

	const onChange = (data) => {
		if (attrs.onChange) {
			getCropUrl().then((url) => attrs.onChange(url))
		}
	}
	const cropper = ref(null)
	const imageClipBody = ref(null)
	const observer = new ResizeObserver((entries) => {
		refreshCrop()
	})
	onMounted(() => {
		observer.observe(imageClipBody.value)
	})
	onBeforeUnmount(() => {
		observer.disconnect()
	})
	const rotateLeft = () => {
		cropper.value.rotateLeft()
	}
	const rotateRight = () => {
		cropper.value.rotateRight()
	}
	const refreshCrop = () => {
		cropper.value.refresh()
	}
	const changeScale = (num = 1) => {
		cropper.value.changeScale(num)
	}
	const getCropUrl = () => {
		return new Promise((resolve, reject) => {
			cropper.value.getCropData(resolve)
		})
	}
	const getCropBlob = () => {
		return new Promise((resolve, reject) => {
			cropper.value.getCropBlob(resolve)
		})
	}
	defineExpose({
		getCropUrl,
		getCropBlob
	})
</script>
<style lang="less" scoped>
	.image-clip {
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: column;
		// height: 100%;
		background: #fff;
		border-radius: calc(2rem * 1.2);
		padding: calc(1.3rem * 1.2) calc(1.3rem * 1.2) calc(2rem * 1.2);
		box-sizing: border-box;

		.image-clip-body {
			width: 100%;
			height: calc(40rem * 1.2);
			// height: 53rem;
			background: yellow;
		}

		.clip_opterate {
			margin: calc(2.7rem * 1.2) auto 0;
			border-radius: calc(1.6rem * 1.2);
			display: flex;
			overflow: hidden;
			border: 1px solid #e2e2e4;
			width: calc(24rem * 1.2);

			.item {
				width: calc(4.7rem * 1.2);
				height: calc(4rem * 1.2);
				display: flex;
				align-items: center;
				justify-content: center;
				border-right: 0.1rem solid #e6e8ea;
				cursor: pointer;

				.icon_chexiao_sec {
					transform: rotateY(180deg); /* 垂直镜像翻转 */
				}

				.operate_icon {
					font-size: calc(1.8rem * 1.2);
					color: rgba(102, 102, 102, 1);
					font-weight: bold;
				}

				.icon_font {
					font-size: calc(2.5rem * 1.2);
					position: relative;
					top: calc(-0.3rem * 1.2);
					user-select: none;
				}

				.icon-shuaxin {
					font-size: calc(1.4rem * 1.2);
				}

				&:last-child {
					border: none;
				}
			}
		}
	}
</style>
