123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <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>
- <div :class="[`${prefixCls}-body`]" ref="ReviewBody">
- <div
- :class="[`${prefixCls}-guide`, `${prefixCls}-guide-prev`]"
- @click.stop="showPrev"
- >
- <i class="el-icon-arrow-left"></i>
- </div>
- <div
- :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>
- </div>
- <div :class="[`${prefixCls}-footer`]">
- <ul>
- <li title="旋转" @click.stop="toRotate">
- <i class="el-icon-refresh-right"></i>
- </li>
- </ul>
- </div>
- </el-dialog>
- </template>
- <script>
- const prefixCls = "cc-image-preview";
- export default {
- name: "simple-image-preview",
- props: {
- curImage: {
- type: Object,
- default() {
- return {};
- }
- }
- },
- data() {
- return {
- prefixCls,
- modalIsShow: false,
- styles: { width: "", height: "", top: "", left: "", transform: "" },
- initWidth: 500,
- transform: {
- scale: 1,
- rotate: 0
- },
- loading: false,
- loadingSetT: null,
- nosition: false
- };
- },
- watch: {
- "curImage.url": {
- handler(val) {
- if (val) {
- this.loadingSetT = setTimeout(() => {
- this.loading = true;
- }, 300);
- this.styles = {
- width: "",
- height: "",
- top: "",
- left: "",
- transform: ""
- };
- }
- }
- }
- },
- methods: {
- reizeImage() {
- if (this.loadingSetT) clearTimeout(this.loadingSetT);
- const imgDom = this.$refs.PreviewImgDetail;
- const { naturalWidth, naturalHeight } = imgDom;
- const imageSize = this.getImageSizePos({
- win: {
- width: this.$refs.ReviewBody.clientWidth,
- height: this.$refs.ReviewBody.clientHeight
- },
- img: {
- width: naturalWidth,
- height: naturalHeight
- },
- rotate: 0
- });
- this.styles = Object.assign(this.styles, {
- width: imageSize.width + "px",
- height: imageSize.height + "px",
- top: imageSize.top + "px",
- left: imageSize.left + "px",
- marginLeft: "auto",
- transform: "none"
- });
- this.transform = {
- scale: 1,
- rotate: 0
- };
- this.loading = false;
- setTimeout(() => {
- this.nosition = false;
- }, 100);
- },
- getImageSizePos({ win, img, rotate }) {
- const imageSize = {
- width: 0,
- height: 0,
- top: 0,
- left: 0
- };
- const isHorizontal = !!(rotate % 180);
- const rateWin = isHorizontal
- ? win.height / win.width
- : win.width / win.height;
- const hwin = isHorizontal
- ? {
- width: win.height,
- height: win.width
- }
- : win;
- const rateImg = img.width / img.height;
- if (rateImg <= rateWin) {
- imageSize.height = Math.min(hwin.height, img.height);
- imageSize.width = Math.floor(
- (imageSize.height * img.width) / img.height
- );
- } else {
- imageSize.width = Math.min(hwin.width, img.width);
- imageSize.height = Math.floor(
- (imageSize.width * img.height) / img.width
- );
- }
- imageSize.left = (win.width - imageSize.width) / 2;
- 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
- setStyleTransform() {
- const { scale, rotate } = this.transform;
- this.styles.transform = `scale(${scale}, ${scale}) rotate(${rotate}deg)`;
- },
- toRotate() {
- this.transform.rotate = this.transform.rotate + 90;
- this.setStyleTransform();
- // 调整图片尺寸
- const { naturalWidth, naturalHeight } = this.$refs.PreviewImgDetail;
- const imageSize = this.getImageSizePos({
- win: {
- width: this.$refs.ReviewBody.clientWidth,
- height: this.$refs.ReviewBody.clientHeight
- },
- img: {
- width: naturalWidth,
- height: naturalHeight
- },
- rotate: this.transform.rotate
- });
- this.styles = Object.assign(this.styles, {
- width: imageSize.width + "px",
- height: imageSize.height + "px",
- top: imageSize.top + "px",
- left: imageSize.left + "px"
- });
- // 360度无缝切换到0度
- if (this.transform.rotate >= 360) {
- setTimeout(() => {
- this.nosition = true;
- this.transform.rotate = 0;
- this.setStyleTransform();
- setTimeout(() => {
- this.nosition = false;
- }, 100);
- }, 200);
- // 200ms当次旋转动画持续时间
- }
- }
- }
- };
- </script>
|