首页 > 其他分享 >图片预览组件 (放大 缩小 旋转 鼠标拖动)

图片预览组件 (放大 缩小 旋转 鼠标拖动)

时间:2023-08-23 15:33:32浏览次数:46  
标签:imgHandle scale 鼠标 预览 拖动 transform element rotate previewImage

效果图

其中的图片初始化 不需要 如果需要可自行修改一下
**完整代码如下 **

点击查看代码
<template>
  <transition name="zoom">
    <div class="previewImage_wrapper" ref="previewImage_wrapper" @wheel="handleScroll">
      <div class="previewImage_image" ref="previewImage_image" @mousedown="onmousedownHandle">
        <img ref="previewImage_img" 
        :style="{
          top: top + 'px',
          left: left + 'px',
        }"
        @click="initImage(previewImgList )"
       :src="previewImgList || ''" />
      </div>
      <div class="previewImage_toolbar">
        <span class="title">{{ title }} {{ currentIndex }}</span>
        <div class="toolbar">
          <span class="previewImage_btn" @click="shrinkHandle">-</span>
          <span class="previewImage_btn" @click="largeHandle">+</span>
          <span class="previewImage_btn" @click="turnLeftHandle">↺</span>
          <span class="previewImage_btn" @click="initImgHandle">▣</span>
          <span class="previewImage_btn" @click="turnRightHandle">↻</span>
        </div>
      </div>
    </div>
  </transition>
</template>
<script>
export default {
  name: 'picture-view',
  props: {
    previewImgList: {
      // url数组
      type: String,
      default: '',
    },
    currentIndex: {
      // 当前图片索引
      type: String,
      default: 0,
    },
    title: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      imageUrl: '',
      imgW: 0,
      imgH: 0,
      top: 0,
      left: 0,
      mousewheelevt: null,
      imgHandle: {
        // 图片控制
        scale: 1,
        rotate: 0,
      },
    };
  },
  mounted() {
    this.imageUrl = this.previewImgList;
    this.initImage();
    this.mousewheelevt = /Firefox/i.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel';
    this.$refs.previewImage_image.addEventListener(this.mousewheelevt, { passive: true });
  },
  beforeDestroy() {
    this.$refs.previewImage_image.removeEventListener(this.mousewheelevt,  { passive: true });
  },
  methods: {
    /* 获取图片真实高宽 */
    getImgSize(url) {
      return new Promise((resolve, reject) => {
        let imgObj = new Image();
        imgObj.src = url;
        imgObj.onload = () => {
          resolve({ width: imgObj.width, height: imgObj.height });
        };
      });
    },

    /* 初始化图片 */ 
    async initImage() {
      if (!this.imageUrl) {
        return;
      }
      let { width, height } = await this.getImgSize(this.imageUrl);
      // let realWidth = width;
      // let realHeight = height;
      // const picBoxW = this.$refs.previewImage_image.clientWidth;
      // const picBboxH = this.$refs.previewImage_image.clientHeight;
      // const WRatio =  picBoxW / realWidth;
      // const HRatio =  picBboxH / realHeight;
      /* 横图 使用宽度比例 */ 
      // if (realWidth >= realHeight) {
      //   this.imgW =  realWidth * WRatio;
      //   this.imgH = realHeight * WRatio;
      //   this.top = (picBboxH - this.imgH) / 2;
      //   this.left = (picBoxW - this.imgW) / 2;
        
      // /* 竖图 */
      // } else {
      //   this.left = (picBoxW - this.imgW) / 2;
      //   this.imgW =  realWidth * HRatio;
      //   this.imgH = realHeight * HRatio;
      // }
    },
    onm ousedownHandle(e) {
      const that = this;
      const element = this.$refs.previewImage_image;
      const imgEle = this.$refs.previewImage_img;
      element.onmousemove = function (el) {
        const ev = el || window.event;
        // 阻止默认事件
        ev.preventDefault();
        that.left += ev.movementX;
        that.top += ev.movementY;
      };
      element.onmouseup = function () {
        element.onmousemove = null;
        element.onmouseup = null;
      };
      if (e.preventDefault) {
        e.preventDefault();
      } else {
        return false;
      }
    },
    // 向左翻转
    async turnLeftHandle() {
      this.imgHandle.rotate = this.imgHandle.rotate - 90;
      await this.$nextTick();
      const element = this.$refs.previewImage_img;
      element.style.transform = `scale(${this.imgHandle.scale}) rotate(${this.imgHandle.rotate}deg)`;
    },
    // 向右翻转
    async turnRightHandle() {
      this.imgHandle.rotate = this.imgHandle.rotate + 90;
      await this.$nextTick();
      const element = this.$refs.previewImage_img;
      element.style.transform = `scale(${this.imgHandle.scale}) rotate(${this.imgHandle.rotate}deg)`;
    },
    // 初始化还原图片缩放旋转控制
    async initImgHandle() {
      this.imgHandle = {
        scale: 1,
        rotate: 0,
      };
      this.top = 0,
      this.left = 0,
      // this.initImage()
      await this.$nextTick();
      const element = this.$refs.previewImage_img;
      element.style.transform = `scale(${this.imgHandle.scale}) rotate(${this.imgHandle.rotate}deg)`;
    },
    // 放大图片
    async largeHandle() {
      this.imgHandle.scale = Number((this.imgHandle.scale + 0.2).toFixed(2)); // 使用toFixed防止小数点精度不准
      const element = this.$refs.previewImage_img;
      element.style.transform = `scale(${this.imgHandle.scale}) rotate(${this.imgHandle.rotate}deg)`;
    },
    // 缩小图片
    async shrinkHandle() {
      if (this.imgHandle.scale === 0.2) {
        // 最低缩放到0.2倍
        return;
      }
      this.imgHandle.scale = Number((this.imgHandle.scale - 0.2).toFixed(2)); // 使用toFixed防止小数点精度不准
      const element = this.$refs.previewImage_img;
      element.style.transform = `scale(${this.imgHandle.scale}) rotate(${this.imgHandle.rotate}deg)`;
    },
    // 上一张图片
    prevImage() {
      if (this.currentIndex === 0) {
        this.currentIndex = this.previewImgList.length - 1;
      } else {
        this.currentIndex--;
      }
      this.initImgHandle();
    },
    // 下一张图片
    nextImage() {
      if (this.currentIndex === this.previewImgList.length - 1) {
        this.currentIndex = 0;
      } else {
        this.currentIndex++;
      }
      this.initImgHandle();
    },
  },
};
</script>
<style lang="scss" scoped>
.title{
color: #fff;
font-size: 24px;
font-weight: 700;
}
.previewImage_wrapper {
  width: 100%;
  height: 100%;
  .previewImage_image {
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    img {
      position: absolute;
      width: 100%;
      height: 100%;
      object-fit: scale-down;
      transition: transform 0.3s ease;
    }
  }
  .previewImage_navigation {
    &_left {
      position: absolute;
      left: 15px;
      top: 50%;
      transform: translate(0, -50%);
      transition: transform 0.2s ease-out;
    }
    &_right {
      position: absolute;
      right: 15px;
      top: 50%;
      transform: translate(0, -50%);
      transition: transform 0.2s ease-out;
    }
    &_left:hover,
    &_right:hover {
      transform: translate(0, -50%) scale(1.2);
    }
  }
  .previewImage_toolbar {
    position: absolute;
    top: 0px;
    left: 50%;
    width: 100%;
    height: 50px;
    transform: translate(-50%, 0);
    display: flex;
    align-items: center;
    justify-content: space-around;
    background: rgba($color: #606266, $alpha: 0.5);
    .toolbar {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
    span {
      margin-right: 10px;
      transition: transform 0.2s ease-out;
      &:hover {
        transform: scale(1.1);
      }
    }
    span:last-child {
      margin-right: 0;
    }
  }
  .previewImage_btn {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 24px;
    font-weight: 700;
    color: #fff;
    border-radius: 50%;
    cursor: pointer;
    user-select: none;  //for chrome
    -moz-user-select:none;//for firefox
  }
}
.zoom-enter,
.zoom-leave-to {
  // 元素进入和离开时的动作
  transform: scale(0);
}
.zoom-enter-active,
.zoom-leave-active {
  // 元素进入和离开时的过渡动画定义
  transition: transform 0.3s;
}

.slide-enter,
.slide-leave-to {
  // 元素进入和离开时的动作
  transform: translateX(100%);
}
.slide-enter-active,
.slide-leave-active {
  // 元素进入和离开时的过渡动画定义
  transition: transform 0.3s ease-in-out;
}
</style>

标签:imgHandle,scale,鼠标,预览,拖动,transform,element,rotate,previewImage
From: https://www.cnblogs.com/babybearcq/p/17651771.html

相关文章

  • KVM安装FreeBSD12桌面,鼠标无法移动
    参考:https://forums.freebsd.org/threads/qemu-kvm-freebsd-guest-running-x-and-a-working-mouse.82460/解决办法:1、Addinputdevice"EvTouchUSBGraphicsTablet"invirt-manager.具体配置如下:<inputtype='tablet'bus='usb'><address......
  • WinForm窗口拖动
    privatePointmypoint;privatevoidpanel1_MouseDown(objectsender,MouseEventArgse){mypoint=newPoint(-e.X,-e.Y);}privatevoidpanel1_MouseMove(objectsender,MouseEventArgse){......
  • C# 鼠标hook和键盘hook
    鼠标HOOKusingSystem;usingSystem.Reflection;usingSystem.Runtime.InteropServices;usingSystem.Windows.Forms;namespaceceshi{publicclassMouseHook{publiceventMouseEventHandlerOnMouseActivity;[DllImport("user32.dll",CallingConv......
  • 采用typescript编写,实现ofd前端预览、验章。
    前言 浏览器内核已支持pdf文件的渲染,这极大的方便了pdf文件的阅读和推广。ofd文件作为国产板式标准,急需一套在浏览器中渲染方案。本人研究ofd多年,分别采用qt、c#开发了ofd阅读器。本人非前端开发人员,对js、typescript并不熟悉,所以对开发web版阅读器迟迟没有下手。但是,本人......
  • [AHK2] 切换鼠标锁定
    介绍这个脚本在看视频时很有用,通过热键可以切换鼠标的锁定,从此不用担心误碰鼠标导致弹出进度条了。脚本使用的热键是ScrollLock的扫描码,一般情况下不会用到,但我很喜欢这个热键。可以根据自身喜好进行更改。注意:这里依旧使用了先前分享的更常用的ToolTip,作用是显示提示,并......
  • 1.9 PC 端预览模板的移动端效果
    一、PC端预览模板的移动端1.访问单张模板%FR_HOME%\webapps\webroot\WEB-INF\reportlets\demo\form\简单自由填报-phone.cpt2.复制模板预览链接1)在FineReport设计器中,打开任意一张普通报表或决策报表,以简单自由填报-phone.cpt为例,选择「移动端预览」,如下图所示:点击......
  • 1.7 App快速预览单张模板
    一、App快速预览单张模板1.环境准备将PC设备与移动设备切换至同一网络环境下。有两种方法:1)手机给电脑开热点2)手机和电脑连接同一热点注:为防止电脑IP未切换到无线网络的IP,请拔掉有线网。2.访问单张模板1)打开FineReport设计器,打开任意一张普通报表或决策报表,以产......
  • 骚操作:使用RxJava实现ImageView的拖动、旋转和缩放
    本文介绍一种使用Rxjava实现图片交互操作的方法。支持单指拖动,双指旋转缩放,效果如下:自定义View首先自定义TrsImageView继承ImageView,设置ScaleType为Matrix,我们使用矩阵计算最终的translate,rotate和scale。publicclassTrsImageViewextendsImageView{publicTrsImageVi......
  • delphi FastReport 预览设置
    FastReport预览设置属性和方法TfrxPreviewOptions.AllowEditpropertyAllowEdit:Boolean;启用或禁用已完成的报表编辑。默认值为True。TfrxPreviewOptions.AllowPreviewEditpropertyAllowPreviewEdit:Boolean;在报表预览中启用就地编辑器。允许用户在没有报告报表设......
  • eclipse调试时鼠标移动到变量上不显示值的问题
    今天同事问一问题,就说在eclipse中调试时,鼠标移动到变量上不显示值,这个原来自己也遇到过,没注意,反正就使用ctrl+shift+i嘛,也可以的,刚查了一下,解决方法如下: Window->Preferences->Java->Editor->Hovers将[VariableValues]选择即可,如果第一个[CombinedHover]已经勾选,则将这个勾去掉......