1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| <template> <div class="container flex"> <div class="img" @mousemove="onMousemove"> <img src="../../public/logos/avatar1.png" alt="" ref="img"> <div ref="small" class="small"></div> </div> <div class="prev"> <img src="../../public/logos/avatar1.png" alt="" ref="prevImg"> </div> </div> </template>
<script setup> import { onMounted, ref } from 'vue';
const scale = ref(1); const img = ref(null); const small = ref(null); const prevImg = ref(null); const offsetX = ref(0); const offsetY = ref(0);
function checkElements() { if (!img.value) throw new Error('找不到图片...'); if (!small.value) throw new Error('找不到取景框...'); if (!prevImg.value) throw new Error('找不到预览图...'); }
onMounted(() => { checkElements(); const imgWidth = img.value.offsetWidth; const smallWidth = small.value.offsetWidth;
scale.value = imgWidth / smallWidth; prevImg.value.style.transform = `scale(${scale.value})`; })
function onMousemove(e) { checkElements(); offsetX.value = Math.max(0, e.offsetX); offsetY.value = Math.max(0, e.offsetY);
const imgWidth = img.value.offsetWidth; const imgHeight = img.value.offsetHeight; const smallWidth = small.value.offsetWidth; const smallHeight = small.value.offsetHeight;
updatePrev({ offsetX: offsetX.value, offsetY: offsetY.value, imgWidth, imgHeight, smallWidth, smallHeight }); }
function updatePrev({ offsetX, offsetY, imgWidth, imgHeight, smallWidth, smallHeight }) { const position = { x: Math.max(0, Math.min(offsetX - smallWidth / 2, imgWidth - smallWidth)), y: Math.max(0, Math.min(offsetY - smallHeight / 2, imgHeight - smallHeight)), }
small.value.style.transform = `translate(${position.x}px, ${position.y}px)`; prevImg.value.style.transform = `translate(${-(position.x - smallWidth) * scale.value}px, ${-(position.y - smallHeight) * scale.value}px) scale(${scale.value})`; } </script>
<style lang='less' scoped> .container { width: 100%; height: 700px; display: flex; justify-content: center; border: 1px rgb(0, 0, 0) solid; flex-direction: column; align-items: center; gap: 10px; }
img { width: 100%; vertical-align: bottom; }
.img { width: 300px; height: 300px; border: 2px solid gray; position: relative; cursor: move; display: flex;
.small { width: 100px; height: 100px; border: 1.5px solid rgba(127, 255, 212, 1); position: absolute; top: 0; left: 0; background-color: rgba(127, 255, 212, 0.382); z-index: 10; pointer-events: none; // 防止鼠标移动到取景框上时,触发鼠标移动事件,导致位置抽搐。 box-sizing: border-box; } }
.prev { width: 300px; height: 300px; border: 1.5px dashed gray; overflow: hidden; position: relative; display: flex;
img { position: absolute; top: 0; right: 0; } } </style>
|