插件名称:vue-photo-zoom-pro

https://github.com/Mater1996/vue-photo-zoom-pro

效果图

 使用:

<template>
<div class="images">
<img style="width: 300px;" @click.stop="showBigPicture(url)" :src="url" alt=""> <!-- 显示大图 -->
<Modal v-model="pictureModal" width="960" footer-hide :closable="closable" class-name="vertical-center-modal">
<photo-zoom :url="bigPictureUrl" :bigWidth="200" :scale="2"
overlayStyle="width: 100%;height: 600px;border-radius: 3px;"></photo-zoom>
</Modal>
</div>
</template>
<script>
import PhotoZoom from '@/components/photo-zoom'
export default {
components: { PhotoZoom },
data() {
return {
url:'http://pic1.win4000.com/wallpaper/2019-01-28/5c4ebd381fc8b.jpg',
bigPictureUrl:'',
pictureModal: false,
closable: false,
}
},
methods: {
showBigPicture(url) {
this.pictureModal = true;
this.bigPictureUrl = url;
},
},
}
</script>

代码中使用了iviewUI的Modal,

组件内容:

   ├── components              
   │   ├── photo-zoom  //放大镜组件
   │   │   ├── index.vue         
   │   │   └── vue-photo-zoom-pro.vue 

index.vue:

<template>
<div style="width: 100%;height: 100%">
<vue-photo-zoom-pro :width="bigWidth" :url="url" :type="type" :scale="scale" :out-show="showType"
:overlayStyle="overlayStyle">
</vue-photo-zoom-pro>
</div>
</template> <script>
import vuePhotoZoomPro from '@/components/photo-zoom/vue-photo-zoom-pro'
export default {
name: 'PicZoom',
components: { vuePhotoZoomPro },
data() {
return {
type: "square",
showType: false,
}
},
props: {
url: {
type: String,
required: true,
// default: require('@/assets/vehicle_img/blank_vehicle.jpg')
},
bigWidth: {
type: Number,
required: true,
default: 168
},
scale: {
type: Number,
required: true,
default: 2
},
overlayStyle: {
type: String,
default: 'width:100%;height:100%'
}
},
}
</script>

vue-photo-zoom-pro.vue:

<template>
<div class="pic-img">
<div class="img-container">
<img ref="img" @load="imgLoaded" :src="url" :style="overlayStyle" @error="imgerrorfun" />
<div class="overlay" @mousemove.stop="!moveEvent && mouseMove($event)"
@mouseout.stop="!leaveEvent && mouseLeave($event)" :style="overlayStyle">
</div>
<div v-if="!hideZoom && imgLoadedFlag &&!hideSelector" :class="['img-selector', {'circle': type === 'circle'}]"
:style="[imgSelectorStyle, imgSelectorSize, imgSelectorPosition, !outShow && imgBg, !outShow && imgBgSize, !outShow && imgBgPosition]">
<slot></slot>
</div>
<div v-if="outShow" v-show="!hideOutShow" :class="['img-out-show', {'base-line': baseline}]"
:style="[imgOutShowSize, imgOutShowPosition, imgBg, imgBgSize, imgBgPosition]">
<div v-if="pointer" class="img-selector-point"></div>
</div>
</div>
</div> </template> <script>
export default {
name: "vue-photo-zoom-pro",
props: {
url: {
type: String,
},
highUrl: String,
width: {
type: Number,
default: 168
},
type: {
type: String,
default: "square",
validator: function (value) {
return ["circle", "square"].indexOf(value) !== -1;
}
},
selectorStyle: {
type: Object,
default() {
return {};
}
},
outShowStyle: {},
scale: {
type: Number,
default: 3
},
moveEvent: {
type: [Object, MouseEvent],
default: null
},
leaveEvent: {
type: [Object, MouseEvent],
default: null
},
hideZoom: {
type: Boolean,
default: false
},
outShow: {
type: Boolean,
default: false
},
pointer: {
type: Boolean,
default: false
},
baseline: {
type: Boolean,
default: false
},
overlayStyle: {
type: String,
default: 'width:100%;height:100%'
},
},
data() {
return {
selector: {
width: this.width,
top: 0,
left: 0,
bgTop: 0,
bgLeft: 0,
rightBound: 0,
bottomBound: 0,
absoluteLeft: 0,
absoluteTop: 0
},
imgInfo: {},
$img: null,
screenWidth: document.body.clientWidth,
outShowInitTop: 0,
outShowTop: 0,
hideOutShow: true,
imgLoadedFlag: false,
hideSelector: false,
timer: null
};
},
watch: {
moveEvent(e) {
this.mouseMove(e);
},
leaveEvent(e) {
this.mouseLeave(e);
},
url(n) {
this.imgLoadedFlag = false;
// let img = require('@/assets/vehicle_img/blank_vehicle.jpg')
// if(n == img){
// this.outShow = false
// }
},
width(n) {
this.initSelectorProperty(n);
},
screenWidth(val) {
if (!this.timer) {
this.screenWidth = val;
this.timer = setTimeout(() => {
this.imgLoaded();
clearTimeout(this.timer);
this.timer = null;
}, 400);
}
}
},
computed: {
addWidth() {
return !this.outShow ? (this.width / 2) * (1 - this.scale) : 0;
},
imgSelectorPosition() {
let { top, left } = this.selector;
return {
top: `${top}px`,
left: `${left}px`
};
},
imgSelectorSize() {
let width = this.selector.width;
return {
width: `${width}px`,
height: `${width}px`
};
},
imgSelectorStyle() {
return this.selectorStyle;
},
imgOutShowSize() {
let {
scale,
selector: { width }
} = this;
return {
width: `${width * scale}px`,
height: `${width * scale}px`
};
},
imgOutShowPosition() {
return {
top: `${this.outShowTop}px`,
right: `${-8}px`
};
},
imgBg() {
return {
backgroundImage: `url(${this.highUrl || this.url})`
};
},
imgBgSize() {
let {
scale,
imgInfo: { height, width }
} = this;
return {
backgroundSize: `${width * scale}px ${height * scale}px`
};
},
imgBgPosition() {
let { bgLeft, bgTop } = this.selector;
return {
backgroundPosition: `${bgLeft}px ${bgTop}px`
};
},
},
mounted() {
this.$img = this.$refs["img"];
},
methods: {
imgLoaded() {
let imgInfo = this.$img.getBoundingClientRect();
if (JSON.stringify(this.imgInfo) != JSON.stringify(imgInfo)) {
this.imgInfo = imgInfo;
this.initSelectorProperty(this.width);
this.resetOutShowInitPosition();
}
if (!this.imgLoadedFlag) {
this.imgLoadedFlag = true;
this.$emit("created", imgInfo);
}
},
mouseMove(e) {
if (!this.hideZoom && this.imgLoadedFlag) {
this.imgLoaded();
const { pageX, pageY, clientY } = e;
const { scale, selector, outShow, addWidth, outShowAutoScroll } = this;
let { outShowInitTop } = this;
const scrollTop = pageY - clientY;
const { absoluteLeft, absoluteTop, rightBound, bottomBound } = selector;
const x = pageX - absoluteLeft; // 选择器的x坐标 相对于图片
const y = pageY - absoluteTop; // 选择器的y坐标
if (outShow) {
if (!outShowInitTop) {
outShowInitTop = this.outShowInitTop = scrollTop + this.imgInfo.top;
}
this.hideOutShow && (this.hideOutShow = false);
this.outShowTop =
scrollTop > outShowInitTop ? scrollTop - outShowInitTop : 0;
}
this.hideSelector && (this.hideSelector = false);
selector.top = y > 0 ? (y < bottomBound ? y : bottomBound) : 0;
selector.left = x > 0 ? (x < rightBound ? x : rightBound) : 0;
selector.bgLeft = addWidth - x * scale; // 选择器图片的坐标位置
selector.bgTop = addWidth - y * scale;
}
},
initSelectorProperty(selectorWidth) {
const selectorHalfWidth = selectorWidth / 2;
const selector = this.selector;
const { width, height, left, top } = this.imgInfo;
const { scrollLeft, scrollTop } = document.documentElement;
selector.width = selectorWidth;
selector.rightBound = width - selectorWidth;
selector.bottomBound = height - selectorWidth;
selector.absoluteLeft = left + selectorHalfWidth + scrollLeft;
selector.absoluteTop = top + selectorHalfWidth + scrollTop;
},
mouseLeave() {
this.hideSelector = true;
if (this.outShow) {
this.hideOutShow = true;
}
},
reset() {
Object.assign(this.selector, {
top: 0,
left: 0,
bgLeft: 0,
bgTop: 0
});
this.resetOutShowInitPosition();
},
resetOutShowInitPosition() {
this.outShowInitTop = 0;
},
imgerrorfun(e) {
// let img = require('@/assets/vehicle_img/blank_vehicle.jpg')
// this.url = img
// e.target.src = img
// e.target.onerror= null
}
}
};
</script> <style scoped>
.img-container { position: relative; }
.overlay { cursor: crosshair; position: absolute; top: 0; left: 0; opacity: 0.5; z-index: 3; }
.img-selector { position: absolute; cursor: crosshair; border: 1px solid rgba(0, 0, 0, 0.1); background-repeat: no-repeat; background-color: rgba(64, 64, 64, 0.6);}
.img-selector.circle {border-radius: 50%;}
.img-out-show {z-index: 5000;position: absolute;background-repeat: no-repeat;-webkit-background-size: cover;background-color: white;transform: translate(100%, 0);}
.img-selector-point {position: absolute;width: 4px;height: 4px;top: 50%;left: 50%;transform: translate(-50%, -50%);background-color: black;}
.img-out-show.base-line::after {position: absolute;box-sizing: border-box;content: "";width: 1px;top: 0;bottom: 0;left: 50%;transform: translateX(-50%);}
.img-out-show.base-line::before {position: absolute;box-sizing: border-box;content: "";height: 1px;border: 1px dashed rgba(0, 0, 0, 0.36);left: 0;right: 0;top: 50%;transform: translateY(-50%);}
</style>

vue 图片放大镜效果的更多相关文章

  1. vue图片放大镜效果

    原作者地址:https://github.com/lemontree2000/vue-magnify 经测试,原插件在使用时有bug,即在预览时进行鼠标滚动,导致遮罩层计算错误.我已修复该bug,特分 ...

  2. Magnifier.js - 支持鼠标滚轮缩放的图片放大镜效果

    Magnifier.js 是一个 JavaScript 库,能够帮助你在图像上实现放大镜效果,支持使用鼠标滚轮放大/缩小功能.放大的图像可以显示在镜头本身或它的外部容器中.Magnifier.js 使 ...

  3. WPF设置VistualBrush的Visual属性制作图片放大镜效果

    原文:WPF设置VistualBrush的Visual属性制作图片放大镜效果 效果图片:原理:设置VistualBrush的Visual属性,利用它的Viewbox属性进行缩放. XAML代码:// ...

  4. 原生javascript实现图片放大镜效果

    当我们在电商网站上购买商品时,经常会看到这样一种效果,当我们把鼠标放到我们浏览的商品图片上时,会出现类似放大镜一样的一定区域的放大效果,方便消费者观察商品.今天我对这一技术,进行简单实现,实现图片放大 ...

  5. 【Demo】jQuery 图片放大镜效果——模仿淘宝图片放大效果

    实现功能: 模仿淘宝图片放大效果,鼠标移动到小图片的某一处,放大镜对应显示大图片的相应位置. 实现效果: 实现代码: <!DOCTYPE html> <html> <he ...

  6. javascript图片放大镜效果展示

    javascript图片放大镜效果展示 <!DOCTYPE html> <html> <head lang="en"> <meta cha ...

  7. canvas知识02:图片放大镜效果

    效果截图: JS代码: <script> // 初始化canvas01和上下文环境 var cav01 = document.getElementById('cav01'); var cx ...

  8. jQuery实现图片放大镜效果

    实现图片放大镜的原理: 给放大镜元素一个对应的html元素为<div class='right'> 设置这个div的宽高固定为某个值(350px,350px) 设置div的css为超出部分 ...

  9. 用css3的cursor:zoom-in/zoom-out实现微博看图片放大镜效果

    1.前言 CSS3的出现解决了很多让人头疼的问题,至少我想很多童鞋都这样认为.css3的cursor属性大家用的应该是非常的多的,我想用的比较多的像cursor:pointer;cursor:help ...

随机推荐

  1. HTML+css基础 css的几种形式 css选择器的两大特性

    3.外联样式 css选择器的两大特性 1.继承性:所有跟文本字体有关的属性都会被子元素继承.且权重是0000. 2.层叠性:就是解决选择器权重大小的一种能力,就是看那个选择器的权重大.谁的权重大听谁的 ...

  2. 【洛谷5438】【XR-2】记忆(数论)

    [洛谷5438][XR-2]记忆(数论) 题面 洛谷 题解 很好的一道题目. 我们首先把所有数的每个质因子的出现次数模二,也就是把最大的完全平方因子给除掉.然后剩下部分一样的就可以产生\(1\)的贡献 ...

  3. 排序算法Java代码实现(二)—— 冒泡排序

    本篇内容: 冒泡排序 冒泡排序 算法思想: 冒泡排序的原理是:从左到右,相邻元素进行比较. 每次比较一轮,就会找到序列中最大的一个或最小的一个.这个数就会从序列的最右边冒出来. 代码实现: /** * ...

  4. Winform中设置ZedGraph鼠标焦点位置画出十字线并在鼠标移出时十字线消失

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  5. WebApi生成文档

    本文包括两个部分: webapi中使用swagger 修改webapi的路由和默认参数 WebApi中使用swagger 项目打开之后,选择 引用,右键,管理NuGet程序包 浏览,搜索swagger ...

  6. [笔记] C# 如何获取文件的 MIME Type

    MIME Type 为何物: MIME 参考手册 svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types 常规方式 对于有文件后 ...

  7. postman强大的团队协作功能

    今天无意在调项目的接口 ,使用的postman工具 ,自己写的接口信息,只能自己看 ,感觉有点不方便,如果一个公司多名测试,如果一个人写接口信息,大家都能用,就会很节约时间 所以团队协作的功能就诞生了 ...

  8. BUUCTF Hack World

    有返回 ,基于布尔得盲注这里用到异或注入(个人喜欢这样用)1^0 返回 Hello, glzjin wants a girlfriend.1^1 返回 Error Occured When Fetch ...

  9. IBM LOTUS DOMINO 9 部署SSL证书

    前言 随着SHA1算法在2016年12月31日以后,将被强制淘汰,所有新的SSL证书都必须支持SHA256算法,所以我们必须将IBM Domino Server升级到9.0以上才可以支持SHA256算 ...

  10. 深度学习中目标检测Object Detection的基础概念及常用方法

    目录 关键术语 方法 two stage one stage 共同存在问题 多尺度 平移不变性 样本不均衡 各个步骤可能出现的问题 输入: 网络: 输出: 参考资料 What is detection ...