两张图片进行分析,可以拖动左边图片进行放大、缩小查看图片差异
底图
<template><div class="box_container"><section><div class="" v-for="item in imgData.imgDataVal" :key="item.id"><img :style="{width: boxStyle.width + '%',top: boxStyle.top,left: boxStyle.left,}" :src="item.src" :alt="item.name" /><div v-if="clickState" class="selectRegion":style="{ top: selectRegionStyle.top, left: selectRegionStyle.left }"></div><div class="text"><p>{{ item.name }}</p></div></div><div ref=" moveDom" id="moveDom"></div></section><p class="p-diff">差别【不准确】: {{ differencePercentage }}%</p></div>
</template><script lang="ts" setup>import imageYT from '../assets/yt.png';
import imageFX from '../assets/fx.png';
import pixelmatch from 'pixelmatch';import { reactive, ref, onMounted, onBeforeUnmount } from 'vue';let differencePercentage = ref(0);
onMounted(() => {compareImages();
});
function compareImages() {const imgA = document.createElement('img');const imgB = document.createElement('img');imgA.onload = () => {imgB.onload = () => {const width = imgA.width;const height = imgA.height;const canvasA = document.createElement('canvas');const canvasB = document.createElement('canvas');canvasA.width = width;canvasA.height = height;canvasB.width = width;canvasB.height = height;const ctxA = canvasA.getContext('2d') as any;const ctxB = canvasB.getContext('2d') as any;ctxA.drawImage(imgA, 0, 0);ctxB.drawImage(imgB, 0, 0);const dataA = ctxA.getImageData(0, 0, width, height);const dataB = ctxB.getImageData(0, 0, width, height);const diff = pixelmatch(dataA.data, dataB.data, null, width, height);differencePercentage.value =100 - parseInt(((diff / (width * height)) * 100).toFixed(2));};imgB.src = imageFX as any;};imgA.src = imageYT as any;
}let imgData = reactive({imgDataVal: [{id: 1,name: '原始图',src: imageYT},{id: 2,name: '分析图',src: imageFX}]
})/*** @description: 添加鼠标事件* @return {*}*/const init = () => {moveDom.value = document.getElementById('moveDom')moveDom.value.addEventListener('mousemove', moveEvent)moveDom.value.addEventListener('wheel', wheelEvent)moveDom.value.addEventListener('mousedown', mousedownEvent)moveDom.value.addEventListener('mouseup', mouseupEvent)moveDom.value.addEventListener('mouseout', mouseoutEvent)moveDom.value.addEventListener('mouseover', mouseoverEvent)
}
onMounted(() => {init()
})const moveDom: any = ref(null);
const images: any = ref(null);
images.value = document.getElementsByClassName('chatImgs');
/*** @description: 卸载鼠标事件* @return {*}*/
onBeforeUnmount(() => {moveDom.value.removeEventListener('mousemove', moveEvent);moveDom.value.removeEventListener('mouseleave', wheelEvent);moveDom.value.removeEventListener('mousedown', mousedownEvent);
});
const boxStyle = ref({width: 50,top: '50%',left: '50%',
});
const selectRegionStyle = ref({top: '50%',left: '50%',
});
const moveX = ref(null);
const moveY = ref(null);/*** @description: 鼠标移动事件* @param {*} e* @return {*}*/
const moveEvent = (e: any) => {moveX.value = e.offsetX;moveY.value = e.offsetY;selectRegionStyle.value.left = `${e.offsetX}px`;selectRegionStyle.value.top = `${e.offsetY}px`;if (clickState.value) {boxStyle.value.top = `${e.offsetY}px`;boxStyle.value.left = `${e.offsetX}px`;}
};
/*** @description: 滚轮事件* @param {*} e* @return {*}*/
const wheelEvent = (e: any) => {if (e.deltaY < 0) {if (boxStyle.value.width > 200) {return;}boxStyle.value.width = boxStyle.value.width + 10;} else {if (boxStyle.value.width < 50) {return;}boxStyle.value.width = boxStyle.value.width - 10;}
};const clickState = ref(false);
const overState = ref(false);
/*** @description: 鼠标左键按下事件* @param {*} e* @return {*}*/
const mousedownEvent = (e: any) => {clickState.value = true;overState.value = true;
};
/*** @description: 鼠标移入事件* @param {*} e* @return {*}*/
const mouseoverEvent = (e: any) => {if (overState.value) {clickState.value = true;}
};
/*** @description: 鼠标左键抬起事件* @param {*} e* @return {*}*/
const mouseupEvent = (e: any) => {clickState.value = false;overState.value = false;
};
/*** @description: 鼠标移出事件* @param {*} e* @return {*}*/
const mouseoutEvent = (e: any) => {clickState.value = false;
};
</script><style scoped lang="scss">
.box_container {width: 100vw;height: 100vh;padding: 0;}section {width: 100%;height: 85%;display: flex;justify-content: center;justify-items: center;>div {flex: 1;height: 100%;position: relative;overflow: hidden;background-color: #0decb8da;box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.07);img {width: 100%;position: absolute;transform: translate(-50%, -50%);z-index: 0;}.selectRegion {position: absolute;width: 100px;height: 100px;transform: translate(-50%, -50%);border: 1px solid rgba(0, 0, 0, 0.3);}}// 左边区域可以拖动#moveDom {width: 49.8%;height: 85.0%;background-color: rgba(0, 0, 0, 0);position: absolute;top: 0;left: 0;cursor: move;}>div:nth-child(1) {margin-right: 5px;}>div:nth-child(2) {cursor: no-drop;margin-left: 5px;}.text {width: 100%;height: 50px;position: absolute;bottom: 0;left: 0;background-color: rgba(0, 0, 0, 0.1);p {width: 100%;height: 100%;line-height: 100%;text-align: center;line-height: 50px;// color: #333;color: #fff;font-weight: 600;letter-spacing: 10px;font-size: 18px;}}
}
.p-diff{display: flex;justify-content: center;margin-top: 20px;font-size: 20px;font-weight:600
}
</style>