| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <template>
- <el-dialog
- :visible.sync="isPreviewing"
- custom-class="c-dialog--transparent"
- :close-on-click-modal="false"
- v-bind="$attrs"
- v-on="$listeners"
- >
- <template v-if="isPreviewing">
- <auto-image
- v-if="isImage"
- class="o-image--preview"
- :src="assetUrl"
- retry
- />
- <video
- v-if="isVideo"
- class="o-video--preview"
- :src="assetUrl"
- autoplay
- controls
- />
- <audio
- v-if="isAudio"
- :src="assetUrl"
- autoplay
- controls
- />
- <i
- class="o-close o-icon el-icon-close has-active u-bold u-pointer"
- @click="onCloseDialog"
- />
- <template v-if="isMultipleFiles">
- <i
- class="o-arrow o-icon el-icon-arrow-left has-active u-bold u-pointer"
- @click="onPresent"
- />
- <i
- class="o-arrow o-icon el-icon-arrow-right has-active u-bold u-pointer"
- @click="onNext"
- />
- <div class="o-total">{{ active + 1 }}/{{ total }}</div>
- </template>
- </template>
- </el-dialog>
- </template>
- <script>
- import { getAssetUrl } from '@/api/asset'
- import { AssetType } from '@/constant'
- export default {
- name: 'PreviewDialog',
- data () {
- return {
- isPreviewing: false,
- isMultipleFiles: false,
- total: 0,
- active: 0,
- source: null
- }
- },
- computed: {
- fileType () {
- return this.source?.type
- },
- isImage () {
- return this.fileType === AssetType.IMAGE
- },
- isVideo () {
- return this.fileType === AssetType.VIDEO
- },
- isAudio () {
- return this.fileType === AssetType.AUDIO
- },
- assetUrl () {
- return this.source && getAssetUrl(this.source.url)
- }
- },
- methods: {
- show (source) {
- this.$sources = source?.files?.length ? source.files : [source]
- this.isMultipleFiles = this.$sources.length > 1
- this.total = this.$sources.length
- this.active = 0
- this.source = this.$sources[this.active]
- this.isPreviewing = true
- },
- onCloseDialog () {
- this.isPreviewing = false
- },
- onPresent () {
- this.active = (this.active - 1 + this.total) % this.total
- this.source = this.$sources[this.active]
- },
- onNext () {
- this.active = (this.active + 1) % this.total
- this.source = this.$sources[this.active]
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .o-image--preview {
- min-width: 96px;
- max-width: 100%;
- min-height: 96px;
- max-height: 100%;
- color: #fff;
- font-size: 32px;
- line-height: 0;
- }
- .o-video--preview {
- max-width: 100%;
- max-height: 100%;
- }
- .o-close {
- position: absolute;
- color: #fff;
- top: 0;
- right: 0;
- transform: translateY(-100%);
- }
- .o-arrow {
- position: absolute;
- color: #fff;
- top: 50%;
- &.el-icon-arrow-left {
- left: 0;
- transform: translate(-100%, -50%);
- }
- &.el-icon-arrow-right {
- right: 0;
- transform: translate(100%, -50%);
- }
- }
- .o-total {
- position: absolute;
- left: 50%;
- bottom: -48px;
- color: #fff;
- font-size: 24px;
- transform: translateX(-50%);
- }
- </style>
|