两张图片进行分析,可以拖动左边图片进行放大、缩小查看图片差异
底图
<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>