The effect
Core problem solving
1. How to achieve the mouse following effect of the left mask 2. How to show the zoom effect
infrastructure
<template>
<div class="goods-image">
<div class="middle">
<img src="https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg" alt="">
</div>
<ul class="small">
<li v-for="i in 4" :key="i">
<img src="https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg" alt="">
</li>
</ul>
</div>
</template>
<style scoped lang="less">
.goods-image {
width: 480px;
height: 400px;
position: relative;
display: flex;
.middle {
width: 400px;
height: 400px;
background: #f5f5f5;
}
.small {
width: 80px;
li {
width: 68px;
height: 68px;
margin-left: 12px;
margin-bottom: 15px;
cursor: pointer;
&:hover, &.active {
border: 2pxsolid @xtxColor; }}}}</style>
Copy the code
Realize the mouse following effect of the left mask
Follow the way of thinking
To prepare the mask container to be moved, change its top, left position by absolute positioning to move real-time monitor mouse position, let the container follow the mouse
The mask layer
<div class="middle">
<img src="https://yanxuanitem.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg" alt="">
+ <div class="layer"></div>
</div>
<style scoped lang="less">
.middle {
width: 400px;
height: 400px;
+ position: relative;
+ cursor: move;
+ .layer{+width: 200px;
+ height: 200px;
+ background: rgba(0.0.0.2);
+ left: 0;
+ top: 0;
+ position: absolute; +}}</style>
Copy the code
The mouse follow
In @vueuse, there is a tool method :useMouseInElement vueuse.org/core/usemou…
import { useMouseInElement } from '@vueuse/core'
setup () {
// Calculate the mouse position based on which element
const target = ref(null)
const { elementX, elementY, isOutside } = useMouseInElement(target)
return { currIndex, target, elementX, elementY, isOutside }
}
Copy the code
+ <div class="middle" ref="target">/ / plus the targetCopy the code
sertup () {
...
const layerStyle = reactive({ top: '0px'.left: '0px' })
watch([elementX,elementY,isOutside], () = > {
// top, left is used to determine the absolute position of the lower mask element
const top = elementY.value - 100
const left = elementX.value - 100
// Assign positions to mask elements
layerStyle.top = top + 'px'
layerStyle.left = left + 'px'
})
return{... Omit, layerStyle}}Copy the code
In the template
+ <div class="layer" :style="layerStyle"></div>
Copy the code
The mask layer can now move with it
Position correction
The mask layer cannot exit the image area
// The position of the mask element cannot be moved out of the middle image range
if (top > 200) top = 200
if (top < 0) top = 0
if (left > 200) left = 200
if (left < 0) left = 0
Copy the code
Effect of implementation
Show magnification
Enlarge mentality
Change background-position-x,background-position-y add responsive data largeStyle to calculate the value of background-position according to the position of the current left mask
Magnification layer
<div class="middle">
+ <div class="large" :style="{backgroundImage: `url(https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg)`}"></div>
<img src="https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg" alt="">
<div class="layer" :style="layerStyle"></div>
</div>
<style scoped lang="less">
.goods-image {
width: 480px;
height: 400px;
position: relative;
display: flex;
+ z-index: 500;
+ .large{+position: absolute;
+ top: 0;
+ left: 412px;
+ width: 400px;
+ height: 400px;
+ box-shadow: 0 0 10px rgba(0.0.0.0.1);
+ background-repeat: no-repeat;
+ background-size: 800px 800px;
+ background-color: #f8f8f8; +}</style>
Copy the code
Zoom in implementation
setup () {
...
+ const largeStyle = reactive({
+ 'background-position-x': '0px',
+ 'background-position-y': '0px'
+ })
watch([elementX,elementY,isOutside], () = > {
// top, left is used to determine the absolute position of the lower mask element
let top = elementY.value - 100
let left = elementX.value - 100
if (top > 200) top = 200
if (top < 0) top = 0
if (left > 200) left = 200
if (left < 0) left = 0
// Assign positions to mask elements
layerStyle.top = top + 'px'
layerStyle.left = left + 'px'
+ largeStyle['background-position-x'] = -2 * left + 'px'
+ largeStyle['background-position-y'] = -2 * top + 'px'
})
return {+largeStyle}
}
Copy the code
In the template
+ <div class="large" :style="{backgroundImage: `url(...) `,... largeStyle}"></div>
Copy the code
Effect to complete
Mouse in display to remove hiding
Use it directly
<div
+ v-show=! "" isOutside"
class="large"
:style="{backgroundImage: `url(...) `,... largeStyle}">
</div>
<img src="https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg" alt="">
<div
+ v-show=! "" isOutside"
class="layer"
:style="layerStyle">
</div>
Copy the code