前端实现放大镜效果原生js实现vue实现

Posted 水香木鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端实现放大镜效果原生js实现vue实现相关的知识,希望对你有一定的参考价值。

🚀作者简介

主页:水香木鱼的博客

专栏:后台管理系统

能量:🔋容量已消耗1%,自动充电中…

笺言:用博客记录每一次成长,书写五彩人生。


📒技术聊斋

(一)原生js实现

具体操作步骤在在注释区域,详细请看 如下代码:👇

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <style type="text/css">
      * 
        margin: 0;
        padding: 0;
      
      /* 原图 */
      .masterMap 
        width: 300px;
        height: 300px;
        float: left;
        margin-top: 100px;
        margin-left: 100px;
        position: relative;
        cursor: move;
      
      img 
        width: 100%;
        height: 100%;
      
      /* 放大图 */
      .enlargedView 
        width: 300px;
        height: 300px;
        float: left;
        margin-top: 100px;
        display: none;
        overflow: hidden;
        position: relative;
      
      /* 放大图 */
      .enlargedView img 
        width: 200%;
        height: 200%;
        position: absolute;
      
      /* 放大镜 */
      .magnifyingGlass 
        width: 100px;
        height: 100px;
        opacity: 0.5;
        background: red;
        position: absolute;
        left: 0;
        top: 0;
        display: none;
      
      .m 
        display: block;
      
    </style>
  </head>
  <body>
    <!-- 原图 -->
    <div class="masterMap">
      <img
        src="https://img1.baidu.com/it/u=3892561140,1187896302&fm=253&fmt=auto&app=138&f=JPEG?w=610&h=484"
      />
      <!--放大镜-->
      <div class="magnifyingGlass"></div>
    </div>

    <!-- 放大图 -->
    <div class="enlargedView">
      <img
        src="https://img1.baidu.com/it/u=3892561140,1187896302&fm=253&fmt=auto&app=138&f=JPEG?w=610&h=484"
      />
    </div>
  </body>
  <script type="text/javascript">
  
    var masterMap = document.getElementsByClassName("masterMap")[0]; //原图
    var enlargedView = document.getElementsByClassName("enlargedView")[0]; //放大图
    var magnifyingGlass = document.getElementsByClassName("magnifyingGlass")[0]; //放大镜
    var img = document.getElementsByTagName("img")[1];
 
    /*鼠标悬停*/
    masterMap.onmouseenter = function () 
      magnifyingGlass.className = "magnifyingGlass m";
      enlargedView.className = "enlargedView m";
    ;
   
    /*鼠标离开*/
    masterMap.onmouseleave = function () 
      magnifyingGlass.className = "magnifyingGlass";
      enlargedView.className = "enlargedView";
    ;

    /*鼠标移动 监听鼠标位置*/
    masterMap.onmousemove = function (event) 
      var event = event || window.event;

      x = event.pageX - masterMap.offsetLeft - magnifyingGlass.offsetWidth / 2;
      y = event.pageY - masterMap.offsetTop - magnifyingGlass.offsetHeight / 2;

      if (x < 0) 
        x = 0;
      
      if (y < 0) 
        y = 0;
      
      if (x > this.offsetWidth - magnifyingGlass.offsetWidth) 
        x = this.offsetWidth - magnifyingGlass.offsetWidth;
      
      if (y > this.offsetHeight - magnifyingGlass.offsetHeight) 
        y = this.offsetHeight - magnifyingGlass.offsetHeight;
      

      magnifyingGlass.style.left = x + "px";
      magnifyingGlass.style.top = y + "px";

      img.style.left = -x * 2 + "px";
      img.style.top = -y * 2 + "px";
    ;
  </script>
</html>

(二)vueuse/core放大镜插件【vue】

使用vue3当中的useMouseInElement 实现

Ⅰ、安装vueuse/core插件

npm install @vueuse/core@5.3.0

Ⅱ、封装公共组件

<!--MagnifyingGlass.vue-->
<template>
  <div class="goods-image">
    <!-- 预览大图 -->
    <div
      class="large"
      :style="[ backgroundImage: `url($images[currIndex])` , bgPosition]"
      v-show="isShow"
    ></div>
    <div class="middle" ref="target">
      <!-- 左侧的大图 -->
      <img :src="images[currIndex]" alt="" />
      <!-- 遮罩层 -->
      <div class="layer" :style="[position]" v-show="isShow"></div>
    </div>
    <ul class="small">
      <!-- 右侧的缩略图 -->
      <li
        v-for="(img, i) in images"
        :key="img"
        :class=" active: i === currIndex "
      >
        <img @mouseenter="currIndex = i" :src="img" alt="" />
      </li>
    </ul>
  </div>
</template>
<script>
import  ref, watch, reactive  from "vue";
import  useMouseInElement  from "@vueuse/core";

export default 
  name: "magnifyingGlass",
  props: 
    images: 
      type: Array,
      default: () => [],
    ,
  ,
  setup(props) 
    const currIndex = ref(0);
    const target = ref(null);
    const isShow = ref(false);
    // 遮罩层的坐标
    const position = reactive(
      left: 0,
      top: 0,
    );
    // 控制背景图的位置
    const bgPosition = reactive(
      backgroundPositionX: 0,
      backgroundPositionY: 0,
    );
    const  elementX, elementY, isOutside  = useMouseInElement(target);
    // 侦听鼠标移动后信息
    watch([elementX, elementY, isOutside], () => 
      // 每次有值发生变化,就读取新的数据即可
      isShow.value = !isOutside.value;
      // 鼠标在图片的区域之外,不需要计算坐标
      if (isOutside.value) return;
      // 水平方向
      if (elementX.value < 100) 
        // 左边界
        position.left = 0;
       else if (elementX.value > 300) 
        // 右边界
        position.left = 200;
       else 
        // 中间的状态
        position.left = elementX.value - 100;
      
      // 垂直方向
      if (elementY.value < 100) 
        // 上边界
        position.top = 0;
       else if (elementY.value > 300) 
        // 下边界
        position.top = 200;
       else 
        // 中间的状态
        position.top = elementY.value - 100;
      
      // console.log(elementX.value, elementY.value, isOutside.value)
      // 计算预览大图背景的位置
      bgPosition.backgroundPositionX = -position.left * 2 + "px";
      bgPosition.backgroundPositionY = -position.top * 2 + "px";
      // 计算左侧遮罩层位置
      position.left += "px";
      position.top += "px";
    );
    return  currIndex, target, isShow, position, bgPosition ;
  ,
;
</script>
<style scoped lang="less">
.goods-image 
  box-sizing: border-box;
  width: 480px;
  height: 400px;
  position: relative;
  display: flex;
  z-index: 500;
  img 
    width: 100%;
    height: 100%;
  
  .large 
    position: absolute;
    top: 0;
    left: 410px;
    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;
  
  .middle 
    width: 400px;
    height: 400px;
    background: #f5f5f5;
    position: relative;
    cursor: move;
    .layer 
      width: 200px;
      height: 200px;
      background: rgba(0, 0, 0, 0.2);
      left: 0;
      top: 0;
      position: absolute;
    
  
  .small 
    margin: 0;
    padding: 0;
    width: 80px;
    li 
      width: 68px;
      height: 68px;
      margin: 10px;
      list-style: none;
      cursor: pointer;
      &:hover,
      &.active 
        border: 2px solid #27ba9b;
      
    
  

</style>

Ⅲ、单页面使用

通过引入import MagnifyingGlass from "../components/magnifyingGlass.vue";//放大镜组件 , components注册实现组件使用

<template>
  <div>
    <MagnifyingGlass :images="images" />
  </div>
</template>
<script>
import MagnifyingGlass from "../components/magnifyingGlass.vue";//放大镜组件
export default 
  components: 
    MagnifyingGlass,
  ,
  data() 
    return 
      //图片数据
      images: [
        "https://profile-avatar.csdnimg.cn/933a530cc73a4bf1a4f92fff138b6841_weixin_48337566.jpg!1",
        "https://www.uoften.com/uploads/reation/bcimg2.png",
        "https://www.uoften.com/uploads/reation/bcimg6.png",
        "https://www.uoften.com/uploads/reation/bcimg9.png",
        "https://www.uoften.com/uploads/reation/bcimg4.png",
      ],
    ;
  ,
;
</script>

📓精品推荐

🔋vue基于promise可以用于浏览器和node.js的网络请求库【axios封装-收藏版】

🔋vue实现按钮弹框【弹出图片、视频、表格、表单等】

🔋前端添加水印效果攻略【vue和原生js添加方式】

🔋vue实现隐藏浏览器右侧滚动条功能

🔋vue实现刷新页面随机切换背景图【适用于登陆界面】


木鱼谢语:感谢各位技术大牛们的点赞👍收藏🌟,每一期都会为大家带来快速适用于业务的文章,让大家做到cv即可。

以上是关于前端实现放大镜效果原生js实现vue实现的主要内容,如果未能解决你的问题,请参考以下文章

通过 jQuery 实现放大镜效果

Vue实现商品放大镜效果

JavaScript之图片操作5

js+css+html实现放大镜效果

前端实现div标签p标签等吸顶效果Vue+原生JS组合写法

原生js--实现放大镜效果