效果
点击预览弹窗:
默认100%
可调整进度条放大缩小,超过100%鼠标可以拖拽图片移动位置
代码:
<template>
<el-dialog
:visible.sync="dialogVisible"
width="30%"
:close-on-press-escape="false"
:close-on-click-modal="false"
:show-close="false"
>
<div class="screen-wrap">
<div
id="playScreen"
class="screen"
>
<!-- 图片类型 getImgUrl是获取图片URL链接 -->
<img
:src="dialogData | getImgUrl"
class="img"
:style="style"
>
</div>
<div class="tool">
<!-- 缩放图片 -->
<div class="enlarge">
<div id="Enlarge">
<!-- 百分比进度条 -->
<div class="scroll">
<div
class="speed"
:style="{width:speed+'%'}"
>
<span class="drag-dom" />
</div>
</div>
<div class="math">
<el-input
v-model="num"
size="mini"
@change="change"
/>
<span class="percentage">%</span>
</div>
</div>
<!-- 关闭按钮 -->
<div class="btn">
<el-button
type="primary"
@click="handleClose"
>
关闭
</el-button>
</div>
</div>
</div>
</div>
<div />
</el-dialog>
</template>
<script>
import {getImgUrl} from '@/utils'
export default {
name: "DialogFilePreview",
filters: {
getImgUrl(val){
return getImgUrl(val)
}
},
props:{
dialogData:{
type:String,
default:()=>""
}
},
data(){
return{
dialogVisible:true,
style:{}, // 图片位置动态改变
num:100, // 初始化百分比
node:'', // 父级
imgDom:'', // 元素
width:'',
height:'',
}
},
computed:{
speed(){ // 进度条位置
return this.change();
}
},
watch:{
num(){ // 监听百分比放大缩小
this.scale();
}
},
mounted() {
this.$nextTick(()=>{
this.node = document.getElementById('playScreen');
let img = document.querySelector('#playScreen .img');
this.imgDom = img;
this.width = img.offsetWidth; // 图片宽度
this.height = img.offsetHeight; // 图片高度
this.drag();
//初始化拖拽移动
this.dragBox(img);
})
},
methods:{
// 关闭弹窗反参父组件
handleClose(){
this.$emit('dialogEmit',false)
},
// 拖拽进度条
drag() {
let speed = document.querySelector('.speed');
let dom = document.querySelector('.drag-dom');
let scroll = document.querySelector('.scroll');
let initX, //初始鼠标x坐标
speedWidth, //当前进度条宽度
scrollWidth, //整个进度条最大宽度
cm, //多少px代表1%
flag = false, //开关
_this = this;
dom.addEventListener("mousedown", (e) => {
flag = true;
initX = e.clientX; //初始鼠标x坐标
speedWidth = speed.clientWidth; // 当前dom宽度
scrollWidth = scroll.clientWidth; // 整个进度条最大宽度
cm = scroll.clientWidth / 300; // 多少px代表1%
}, false);
document.addEventListener("mousemove", function (e) {
if (flag) {
let nowX = e.clientX,
disX = nowX - initX,
disWidth = disX + speedWidth;
disWidth < 10 ? speed.style.width = "10px" : disWidth > scrollWidth ? speed.style.width = scrollWidth + "px" : speed.style.width = disWidth + "px";
let w = Math.round(disWidth / cm);
_this.num = w > 300 ? 300 : w < 10 ? 10 : w;
_this.imgDom.style.maxWidth = _this.num + '%'; // 更新最大值
_this.imgDom.style.maxHeight = _this.num + '%';
}
});
document.addEventListener("mouseup", async () => {
if (flag) {
flag = false;
document.onmousemove = null;
document.mouseup = null;
this.scale();
}
}, false);
},
// 缩放
scale() {
let _this = this;
_this.$nextTick(() => {
let proportion = Number(_this.num) / 100; // 得到放大多少倍
let w = _this.node.offsetWidth; // 得到父级宽度
let h = _this.node.offsetHeight;
let left = (w - (_this.width * proportion)) / 2; // 使没有超出时居中
let top = (h - (_this.height * proportion)) / 2;
// left/top:如果超出父级就默认0,否则计算居中;w/h是计算倍数后的大小
_this.style = {
left:left + 'px',
top: top + 'px',
width: _this.width * proportion + 'px',
height: _this.height * proportion + 'px'
};
});
},
// 进度条修改
change() {
let _this = this;
if(_this.imgDom) {
//判断是否输入的是正确数字格式
isNaN(_this.num) ? _this.num = 100 : _this.num = Math.round(_this.num);
if (_this.num > 300) {
_this.num = 300;
}
return _this.num / 3
}
},
// 拖拽移动
dragBox(drag) {
if (!drag) return;
let initX, //初始鼠标x坐标
initY, //初始鼠标Y坐标
dragAble = false, //开关
wrapLeft, //当前dom left坐标
wrapTop, //当前dom top坐标
_this = this;
drag.onmousedown = function(ev) {// 鼠标按下事件
let e = ev || window.event;
e.preventDefault();
//判断是否有操作权限并且当前缩放比例必须大于100%才能拖拽
if (_this.num > 100) {
dragAble = true;
wrapLeft = _this.getCss(drag, "left"); //当前dom left坐标
wrapTop = _this.getCss(drag, "top"); //当前dom top坐标
initX = e.clientX; //初始鼠标x坐标
initY = e.clientY; //初始鼠标y坐标
}
_this.node.onmousemove = function(ev1) {
let e1 = ev1 || window.event;
if (dragAble) {
e1.preventDefault();
let nowX = e1.clientX,
nowY = e1.clientY,
disX = nowX - initX,
disY = nowY - initY,
left = wrapLeft + disX, //当前x坐标
top = wrapTop + disY; //当前y坐标
drag.style.left = left + "px";
drag.style.top = top + "px";
}
}
}
document.onmouseup = function() {
if (dragAble) {
dragAble = false;
// 鼠标抬起
_this.node.onmousemove = null;
}
}
},
// 获取css
getCss(ele, prop) {
return parseInt(window.getComputedStyle(ele)[prop]);
}
}
}
</script>
<style scoped lang="scss">
::v-deep .el-dialog {
width: 700px !important;
height: 580px !important;
.el-dialog__body{
padding: 0;
height: 100%;
}
}
.screen-wrap {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
.screen {
flex: 1;
overflow: hidden;
background: #474747;
position: relative;
user-select: none;
justify-content: center;
align-items: center;
display: flex;
overflow: hidden;
.share-media-play {
width: 100%;
height: 100%;
div {
width: 100%;
height: 100%;
}
}
.img {
cursor: grabbing;
position: absolute;
max-width: 100%;
max-height: 100%;
}
}
.tool {
height: 90px;
.enlarge {
flex: 1;
padding-left: 20px;
height: 100%;
width: 100%;
display: flex;
position: relative;
#Enlarge {
display: flex;
height: 100%;
width: 60%;
align-items: center;
.scroll {
flex: 1;
height: 5px;
background: #848992;
border-radius: 2px;
position: relative;
.speed {
height: 5px;
background: #33ccff;
position: relative;
span {
width: 12px;
height: 12px;
display: block;
background: #33CCFF;
border-radius: 6px;
position: absolute;
right: -6px;
top: -3.5px;
cursor: pointer;
}
}
}
.math {
margin-left: 20px;
width: 80px;
/deep/ .el-input {
width: 50px;
.el-input__inner {
padding: 0;
text-align: center;
}
}
.percentage {
display: inline-block;
color: #594C4C;
height: 28px;
line-height: 28px;
margin-left: 10px;
}
}
}
.btn{
position: absolute;
right: 10px;
top: 0;
bottom: 0;
display: flex;
align-items: center;
}
}
}
}
</style>
最近整理21年笔记发现那时候我还是喜欢用原生js来实现一些特定的需求,挺好