|
@@ -1,93 +1,89 @@
|
|
|
<template>
|
|
|
- <el-dialog
|
|
|
- :class="[prefixCls, 'opacity-dialog']"
|
|
|
- :visible.sync="modalIsShow"
|
|
|
- title="图片预览"
|
|
|
- fullscreen
|
|
|
- append-to-body
|
|
|
- :close-on-click-modal="false"
|
|
|
- :close-on-press-escape="false"
|
|
|
- >
|
|
|
- <div slot="title"></div>
|
|
|
- <div slot="footer"></div>
|
|
|
- <div :class="[`${prefixCls}-close`]" @click="cancel">
|
|
|
- <i class="el-icon-circle-close"></i>
|
|
|
+ <div class="image-contain">
|
|
|
+ <div
|
|
|
+ v-if="showGuide"
|
|
|
+ :class="[`${prefixCls}-guide`, `${prefixCls}-guide-prev`]"
|
|
|
+ @click.stop="showPrev"
|
|
|
+ >
|
|
|
+ <i class="el-icon-arrow-left"></i>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="showGuide"
|
|
|
+ :class="[`${prefixCls}-guide`, `${prefixCls}-guide-next`]"
|
|
|
+ @click.stop="showNext"
|
|
|
+ >
|
|
|
+ <i class="el-icon-arrow-right"></i>
|
|
|
</div>
|
|
|
|
|
|
- <div :class="[`${prefixCls}-body`]" ref="ReviewBody">
|
|
|
- <div
|
|
|
- v-if="!simple"
|
|
|
- :class="[`${prefixCls}-guide`, `${prefixCls}-guide-prev`]"
|
|
|
- @click.stop="showPrev"
|
|
|
- >
|
|
|
- <i class="el-icon-arrow-left"></i>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-if="!simple"
|
|
|
- :class="[`${prefixCls}-guide`, `${prefixCls}-guide-next`]"
|
|
|
- @click.stop="showNext"
|
|
|
- >
|
|
|
- <i class="el-icon-arrow-right"></i>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- :class="[
|
|
|
- `${prefixCls}-imgs`,
|
|
|
- { [`${prefixCls}-imgs-nosition`]: nosition }
|
|
|
- ]"
|
|
|
- :style="styles"
|
|
|
- v-if="modalIsShow"
|
|
|
- >
|
|
|
- <img
|
|
|
- :key="curImage.url"
|
|
|
- :src="curImage.url"
|
|
|
- :alt="curImage.filename"
|
|
|
- ref="PreviewImgDetail"
|
|
|
- @load="reizeImage"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div :class="[`${prefixCls}-none`]" v-if="!curImage.url">
|
|
|
- <i class="el-icon-picture"></i>
|
|
|
- <p>暂无数据</p>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div :class="[`${prefixCls}-loading`]" v-show="loading">
|
|
|
- <i class="el-icon-loading"></i>
|
|
|
- </div>
|
|
|
+ <!-- image -->
|
|
|
+ <div
|
|
|
+ :class="[
|
|
|
+ `${prefixCls}-image`,
|
|
|
+ { [`${prefixCls}-image-nosition`]: nosition }
|
|
|
+ ]"
|
|
|
+ :style="styles"
|
|
|
+ v-move-ele.prevent.stop="{ mouseMove }"
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ :key="image.url"
|
|
|
+ :src="image.url"
|
|
|
+ :alt="imageName"
|
|
|
+ ref="PreviewImgDetail"
|
|
|
+ @load="resizeImage"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div :class="[`${prefixCls}-none`]" v-if="!image.url">
|
|
|
+ <i class="el-icon-picture"></i>
|
|
|
+ <p>暂无数据</p>
|
|
|
</div>
|
|
|
|
|
|
- <div v-if="!simple" :class="[`${prefixCls}-footer`]">
|
|
|
+ <div :class="[`${prefixCls}-loading`]" v-show="loading">
|
|
|
+ <i class="el-icon-loading"></i>
|
|
|
+ </div>
|
|
|
+ <!-- action -->
|
|
|
+ <div v-if="showAction" :class="[`${prefixCls}-action`]">
|
|
|
<ul>
|
|
|
+ <li title="合适大小" @click.stop="toOrigin">
|
|
|
+ <i class="el-icon-rank" />
|
|
|
+ </li>
|
|
|
<li title="旋转" @click.stop="toRotate">
|
|
|
<i class="el-icon-refresh-right"></i>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
- </el-dialog>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-const prefixCls = "cc-image-preview";
|
|
|
+import MoveEle from "../plugins/move-ele";
|
|
|
+const prefixCls = "image-contain";
|
|
|
|
|
|
export default {
|
|
|
- name: "simple-image-preview",
|
|
|
+ name: "image-contain",
|
|
|
props: {
|
|
|
- curImage: {
|
|
|
+ image: {
|
|
|
type: Object,
|
|
|
default() {
|
|
|
- return {};
|
|
|
+ return { url: "", filename: "" };
|
|
|
}
|
|
|
},
|
|
|
- simple: {
|
|
|
+ showAction: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ showGuide: {
|
|
|
type: Boolean,
|
|
|
- default: false
|
|
|
+ default: true
|
|
|
}
|
|
|
},
|
|
|
+ directives: { MoveEle },
|
|
|
data() {
|
|
|
return {
|
|
|
prefixCls,
|
|
|
- modalIsShow: false,
|
|
|
styles: { width: "", height: "", top: "", left: "", transform: "" },
|
|
|
initWidth: 500,
|
|
|
+ minScale: 0.5,
|
|
|
+ maxScale: 5,
|
|
|
transform: {
|
|
|
scale: 1,
|
|
|
rotate: 0
|
|
@@ -97,34 +93,44 @@ export default {
|
|
|
nosition: false
|
|
|
};
|
|
|
},
|
|
|
- watch: {
|
|
|
- "curImage.url": {
|
|
|
- handler(val) {
|
|
|
- if (val) {
|
|
|
- this.loadingSetT = setTimeout(() => {
|
|
|
- this.loading = true;
|
|
|
- }, 300);
|
|
|
- this.styles = {
|
|
|
- width: "",
|
|
|
- height: "",
|
|
|
- top: "",
|
|
|
- left: "",
|
|
|
- transform: ""
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
+ // watch: {
|
|
|
+ // "image.url": {
|
|
|
+ // handler(val) {
|
|
|
+ // if (val) {
|
|
|
+ // this.loadingSetT = setTimeout(() => {
|
|
|
+ // this.loading = true;
|
|
|
+ // }, 300);
|
|
|
+ // this.styles = {
|
|
|
+ // width: "",
|
|
|
+ // height: "",
|
|
|
+ // top: "",
|
|
|
+ // left: "",
|
|
|
+ // transform: ""
|
|
|
+ // };
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ computed: {
|
|
|
+ imageName() {
|
|
|
+ if (this.image.filename) return this.image.filename;
|
|
|
+
|
|
|
+ const st1 = this.image.url.split("?")[0] || "";
|
|
|
+ const st2 = st1.split("/").slice(-1) || "";
|
|
|
+ return st2;
|
|
|
}
|
|
|
},
|
|
|
+ mounted() {
|
|
|
+ this.registWheelHandle();
|
|
|
+ },
|
|
|
methods: {
|
|
|
- reizeImage() {
|
|
|
- if (this.loadingSetT) clearTimeout(this.loadingSetT);
|
|
|
-
|
|
|
+ resizeImage() {
|
|
|
const imgDom = this.$refs.PreviewImgDetail;
|
|
|
const { naturalWidth, naturalHeight } = imgDom;
|
|
|
const imageSize = this.getImageSizePos({
|
|
|
win: {
|
|
|
- width: this.$refs.ReviewBody.clientWidth,
|
|
|
- height: this.$refs.ReviewBody.clientHeight
|
|
|
+ width: this.$el.clientWidth,
|
|
|
+ height: this.$el.clientHeight
|
|
|
},
|
|
|
img: {
|
|
|
width: naturalWidth,
|
|
@@ -186,26 +192,49 @@ export default {
|
|
|
imageSize.top = (win.height - imageSize.height) / 2;
|
|
|
return imageSize;
|
|
|
},
|
|
|
- cancel() {
|
|
|
- this.modalIsShow = false;
|
|
|
- this.$emit("on-close");
|
|
|
- },
|
|
|
- open() {
|
|
|
- this.modalIsShow = true;
|
|
|
- },
|
|
|
showPrev() {
|
|
|
this.$emit("on-prev");
|
|
|
- // this.initData();
|
|
|
},
|
|
|
showNext() {
|
|
|
this.$emit("on-next");
|
|
|
- // this.initData();
|
|
|
},
|
|
|
// dome-move
|
|
|
+ registWheelHandle() {
|
|
|
+ this.$el.addEventListener("wheel", e => {
|
|
|
+ e.preventDefault();
|
|
|
+ this.mouseWheel(e.wheelDeltaY);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ mouseMove({ left, top }) {
|
|
|
+ this.styles.left = left + "px";
|
|
|
+ this.styles.top = top + "px";
|
|
|
+ },
|
|
|
+ mouseWheel(delta) {
|
|
|
+ if (delta < 0) {
|
|
|
+ this.toMagnify();
|
|
|
+ } else {
|
|
|
+ this.toShrink();
|
|
|
+ }
|
|
|
+ },
|
|
|
setStyleTransform() {
|
|
|
const { scale, rotate } = this.transform;
|
|
|
this.styles.transform = `scale(${scale}, ${scale}) rotate(${rotate}deg)`;
|
|
|
},
|
|
|
+ toOrigin() {
|
|
|
+ this.transform.scale = 1;
|
|
|
+ this.setStyleTransform();
|
|
|
+ this.resizeImage();
|
|
|
+ },
|
|
|
+ toMagnify() {
|
|
|
+ const scale = (this.transform.scale * 1.2).toFixed(2);
|
|
|
+ this.transform.scale = scale >= this.maxScale ? this.maxScale : scale;
|
|
|
+ this.setStyleTransform();
|
|
|
+ },
|
|
|
+ toShrink() {
|
|
|
+ const scale = (this.transform.scale * 0.75).toFixed(2);
|
|
|
+ this.transform.scale = scale <= this.minScale ? this.minScale : scale;
|
|
|
+ this.setStyleTransform();
|
|
|
+ },
|
|
|
toRotate() {
|
|
|
this.transform.rotate = this.transform.rotate + 90;
|
|
|
this.setStyleTransform();
|
|
@@ -213,8 +242,8 @@ export default {
|
|
|
const { naturalWidth, naturalHeight } = this.$refs.PreviewImgDetail;
|
|
|
const imageSize = this.getImageSizePos({
|
|
|
win: {
|
|
|
- width: this.$refs.ReviewBody.clientWidth,
|
|
|
- height: this.$refs.ReviewBody.clientHeight
|
|
|
+ width: this.$el.clientWidth,
|
|
|
+ height: this.$el.clientHeight
|
|
|
},
|
|
|
img: {
|
|
|
width: naturalWidth,
|