123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- <template>
- <transition name="fade">
- <div
- class="hevue-imgpreview-wrap"
- id="hevue-imgpreview-wrap"
- v-if="visible"
- ref="heImg"
- @mouseup="removeMove('pc')"
- @touchend="removeMove('mobile')"
- @click.stop="clickMask"
- >
- <div class="he-img-wrap">
- <div
- class="heimgfont hevue-img-status-icon rotate-animation"
- v-show="imgState === 1"
- >
- 
- </div>
-
- <img
- :src="imgurl"
- ref="heImView"
- @click.stop=""
- v-show="imgState === 2"
- class="he-img-view"
- :style="
- 'transform: scale(' +
- imgScale +
- ') rotate(' +
- imgRotate +
- 'deg);margin-top:' +
- imgTop +
- 'px;margin-left:' +
- imgLeft +
- 'px;' +
- maxWH
- "
- @mousedown="addMove"
- @touchstart="addMoveMobile"
- />
-
- <div class="heimgfont hevue-img-status-icon" v-show="imgState === 3">
- 
- </div>
-
- <div
- class="heimgfont he-close-icon"
- @click.stop="close({ way: 'closeBtn' })"
- v-if="closeBtn"
- >
- 
- </div>
-
- <div
- class="arrow arrow-left heimgfont"
- @click.stop="toogleImg(false, 'btn')"
- v-if="arrowBtn && multiple"
- >
- 
- </div>
-
- <div
- class="arrow arrow-right heimgfont"
- @click.stop="toogleImg(true, 'btn')"
- v-if="arrowBtn && multiple"
- >
- 
- </div>
-
- <div class="he-control-bar-wrap" v-if="controlBar">
- <div class="he-control-bar" @click.stop>
-
- <div
- class="he-control-btn heimgfont"
- @click.stop="scaleFunc(-0.15)"
- >
- 
- </div>
-
- <div class="he-control-btn heimgfont" @click.stop="scaleFunc(0.15)">
- 
- </div>
-
- <div
- class="he-control-btn heimgfont"
- v-show="isFull"
- @click.stop="imgToggle"
- >
- 
- </div>
-
- <div
- class="he-control-btn heimgfont"
- v-show="!isFull"
- @click.stop="imgToggle"
- >
- 
- </div>
-
- <div class="he-control-btn heimgfont" @click.stop="rotateFunc(-90)">
- 
- </div>
-
- <div class="he-control-btn heimgfont" @click.stop="rotateFunc(90)">
- 
- </div>
-
-
- </div>
- </div>
-
- <div class="he-control-num" v-if="controlBar && multiple">
- {{ imgIndex + 1 }} / {{ imgList.length }}
- </div>
- </div>
- </div>
- </transition>
- </template>
- <script>
- export default {
- name: 'hevue-img-preview',
- data() {
- return {
-
-
- visible: false,
- imgScale: 1,
- imgTop: 0,
- imgLeft: 0,
- imgRotate: 0,
- isFull: false,
- maxWH: 'max-width:100%;max-height:100%;',
- clientX: 0,
- clientY: 0,
- imgIndex: 0,
- canRun: true,
- imgurl: '',
- imgState: 1,
- start: [{}, {}],
- mobileScale: 0,
-
-
- url: '',
- nowImgIndex: 0,
- multiple: false,
- imgList: [],
-
- controlBar: true,
- closeBtn: true,
- arrowBtn: true,
- keyboard: false,
- clickMaskCLose: false,
- closeFn: null,
- changeFn: null,
- }
- },
- mounted() {
- this.initImg()
- },
- watch: {
- url() {
- this.initImg()
- },
- visible: {
- handler(newV) {
- if (newV) {
- this.$nextTick(() => {
- let _dom = document.getElementById('hevue-imgpreview-wrap')
- _dom.onmousewheel = this.scrollFunc
-
- document.body.addEventListener('DOMMouseScroll', this.scrollFunc)
-
- document.ondragstart = function () {
- return false
- }
-
- if (this.multiple) {
- if (Array.isArray(this.imgList) && this.imgList.length > 0) {
- this.imgIndex = Number(this.nowImgIndex) || 0
-
- this.changeUrl(this.imgList[this.imgIndex], this.imgIndex)
- } else {
-
- }
- } else {
- this.changeUrl(this.url)
- }
-
- if (this.keyboard) {
- document.addEventListener('keydown', this.keyHandleDebounce)
- }
- })
- }
- },
- immediate: true,
- },
- },
- methods: {
- show() {
- this.visible = true
- },
- close(data) {
- this.initImg()
-
-
-
- document.body.removeEventListener('DOMMouseScroll', this.scrollFunc)
-
- document.ondragstart = null
-
- if (this.keyboard) {
- document.removeEventListener('keydown', this.keyHandleDebounce)
- }
- this.visible = false
- this.closeFn && this.closeFn(data)
- },
- initImg() {
- this.mobileScale = 1
- this.imgScale = 1
- this.imgRotate = 0
- this.imgTop = 0
- this.imgLeft = 0
- },
-
- toogleImg(bool, way) {
- let fromIndex = this.imgIndex
- if (bool) {
- this.imgIndex++
- if (this.imgIndex > this.imgList.length - 1) {
- this.imgIndex = 0
- }
- } else {
- this.imgIndex--
- if (this.imgIndex < 0) {
- this.imgIndex = this.imgList.length - 1
- }
- }
- this.changeFn &&
- this.changeFn({
- type: bool ? 'next' : 'prev',
- fromImgIndex: fromIndex,
- fromImgUrl: this.imgList[fromIndex],
- toImgIndex: this.imgIndex,
- toImgUrl: this.imgList[this.imgIndex],
- way,
- })
-
- this.changeUrl(this.imgList[this.imgIndex], this.imgIndex)
- },
-
-
- changeUrl(url, index) {
- this.imgState = 1
- let img = new Image()
- img.src = url
- img.onload = () => {
-
- if (index != undefined && index == this.imgIndex) {
- this.imgState = 2
- this.imgurl = url
- } else if (index == undefined) {
- this.imgState = 2
- this.imgurl = url
- }
- }
- img.onerror = () => {
- if (index != undefined && index == this.imgIndex) {
- this.imgState = 3
- } else if (index == undefined) {
- this.imgState = 3
- }
- }
- },
-
- rotateFunc(deg) {
- this.imgRotate += deg
- },
-
- scaleFunc(num, bool) {
- if (this.imgScale <= 0.2 && num < 0) return
- if (bool) {
- this.imgScale = num
- } else {
- this.imgScale += num
- }
- },
-
- imgToggle() {
- this.initImg()
- if (this.isFull) {
- this.maxWH = 'max-width:100%;max-height:100%;'
- } else {
- this.maxWH = ''
- }
- this.isFull = !this.isFull
- },
-
- scrollFunc(e) {
- e = e || window.event
-
-
- e.delta = e.wheelDelta || -e.detail
- e.preventDefault()
- if (e.delta > 0) {
-
- this.scaleFunc(0.05)
- }
- if (e.delta < 0) {
-
- this.scaleFunc(-0.05)
- }
- },
-
- addMove(e) {
- e = e || window.event
- this.clientX = e.clientX
- this.clientY = e.clientY
- this.$refs.heImg.onmousemove = this.moveFunc
- },
-
- addMoveMobile(e) {
- e.preventDefault()
- e = e || window.event
- if (e.touches.length > 1) {
- this.start = e.touches
- } else {
- this.clientX = e.touches[0].pageX
- this.clientY = e.touches[0].pageY
- }
-
- this.$refs.heImg.ontouchmove = this.moveFuncMobile
- },
-
- moveFunc(e) {
- e = e || window.event
- e.preventDefault()
- let movementX = e.clientX - this.clientX
- let movementY = e.clientY - this.clientY
-
- this.imgLeft += movementX * 2
- this.imgTop += movementY * 2
- this.clientX = e.clientX
- this.clientY = e.clientY
- },
-
- moveFuncMobile(e) {
- e = e || window.event
- if (e.touches.length > 1) {
- var now = e.touches
- var scale =
- this.getDistance(now[0], now[1]) /
- this.getDistance(this.start[0], this.start[1])
-
- if (this.mobileScale) {
- if (scale > 1) {
-
- this.scaleFunc(scale + this.mobileScale - 1, true)
- } else {
-
- this.scaleFunc(scale * this.mobileScale, true)
- }
- } else {
- this.scaleFunc(scale, true)
- }
- } else {
- let touch = e.touches[0]
- e.preventDefault()
- let movementX = touch.pageX - this.clientX
- let movementY = touch.pageY - this.clientY
-
- this.imgLeft += movementX * 2
- this.imgTop += movementY * 2
- this.clientX = touch.pageX
- this.clientY = touch.pageY
- }
- },
-
- removeMove(type) {
- if (type === 'pc') {
- this.$refs.heImg.onmousemove = null
- } else {
- this.mobileScale = this.imgScale
- this.$refs.heImg.ontouchmove = null
- }
- },
- keyHandleDebounce(e) {
- if (this.canRun) {
-
- this.keyHandle(e)
- this.canRun = false
- setTimeout(() => {
- this.canRun = true
- }, 300)
- }
- },
-
- keyHandle(e) {
- e = window.event || e
- var key = e.keyCode || e.which || e.charCode
- switch (key) {
- case 27:
- this.close({ way: 'esc' })
- break
- case 65:
- if (this.multiple) {
- this.toogleImg(false, 'key-a')
- }
- break
- case 68:
- if (this.multiple) {
- this.toogleImg(true, 'key-d')
- }
- break
- case 87:
- this.scaleFunc(0.15)
- break
- case 83:
- this.scaleFunc(-0.15)
- break
- case 81:
- this.rotateFunc(-90)
- break
- case 69:
- this.rotateFunc(90)
- break
- case 82:
- this.initImg()
- break
- default:
- break
- }
- },
-
- clickMask() {
- if (this.clickMaskCLose) {
- this.close({ way: 'mask' })
- }
- },
-
- getDistance(p1, p2) {
- var x = p2.pageX - p1.pageX,
- y = p2.pageY - p1.pageY
- return Math.sqrt(x * x + y * y)
- },
-
- downloadIamge() {
-
- let image = new Image()
-
- image.setAttribute('crossOrigin', 'anonymous')
- image.onload = function () {
- let canvas = document.createElement('canvas')
- canvas.width = image.width
- canvas.height = image.height
- let context = canvas.getContext('2d')
- context.drawImage(image, 0, 0, image.width, image.height)
- let url = canvas.toDataURL('image/png')
- let a = document.createElement('a')
- let event = new MouseEvent('click')
- a.download = 'photo' + +new Date()
- a.href = url
- a.dispatchEvent(event)
- }
- image.onerror = function (err) {
- console.log('图片信息不正确或图片服务器禁止访问')
- console.log(err)
- }
- if (this.multiple) {
- image.src = this.imgList[this.imgIndex]
- } else {
- image.src = this.url
- }
- },
- },
- }
- </script>
- <style scoped>
- @import './iconfont/iconfont.css';
- @import './css/default.css';
- </style>
|