ViewOperation.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <template>
  2. <div class="per-layout" ref="layout">
  3. <div id="box" class="content" :style="contentStyle">
  4. <slot />
  5. </div>
  6. </div>
  7. </template>
  8. <script>
  9. import {setGesture} from '@/utils'
  10. import browser from '@/utils/browser'
  11. const MAXSCALE = 1
  12. const MINSCALE = 1
  13. const RANGE = 0.1
  14. const wh = {width: window.innerHeight * (1920 / 1080), height: window.innerHeight}
  15. export default {
  16. data () {
  17. return {
  18. wh,
  19. width: wh.width,
  20. height: wh.height,
  21. tscale: 1,
  22. translate: {
  23. x: 0,
  24. y: 0
  25. },
  26. isFireFox: browser.gecko,
  27. ismobile: browser.mobile
  28. }
  29. },
  30. computed: {
  31. contentStyle () {
  32. let tempW = Math.round(this.tscale * wh.width)
  33. let tempH = Math.round(this.tscale * wh.height)
  34. let val = `translateX(calc(-50% + ${this.translate.x}px))
  35. translateY(calc(-50% + ${this.translate.y}px))
  36. `
  37. let width = `${tempW % 2 === 0 ? tempW : tempW + 1}px`
  38. let height = `${tempH % 2 === 0 ? tempH : tempH + 1}px`
  39. let top = `${Math.round(0.5 * wh.height)}px`
  40. return {transform: val, width, height, top}
  41. },
  42. wLimit () {
  43. return this.ismobile ? ((wh.width * Math.max(this.tscale, 1))) / 2 - window.innerWidth / 2 : ((wh.width * this.tscale) - wh.width) / 2
  44. },
  45. hLimit () {
  46. return ((wh.height * this.tscale) - wh.height) / 2
  47. }
  48. },
  49. watch: {
  50. tscale () {
  51. this.$emit('closeItem')
  52. this.translate.x = Math.min(Math.max(this.translate.x, -this.wLimit), this.wLimit)
  53. this.translate.y = Math.min(Math.max(this.translate.y, -this.hLimit), this.hLimit)
  54. }
  55. },
  56. methods: {
  57. readyMove (ev) {
  58. // ev.preventDefault()
  59. ev.stopPropagation()
  60. let startX, startY
  61. if (ev.screenX) {
  62. startX = ev.screenX
  63. startY = ev.screenY
  64. } else {
  65. startX = ev.touches[0].clientX
  66. startY = ev.touches[0].clientY
  67. }
  68. let x = this.translate.x
  69. let y = this.translate.y
  70. let moveHandle = ev => {
  71. let moveX, moveY
  72. if (ev.screenX) {
  73. moveX = ev.screenX
  74. moveY = ev.screenY
  75. } else {
  76. moveX = ev.touches[0].clientX
  77. moveY = ev.touches[0].clientY
  78. }
  79. this.translate.x = Math.min(Math.max((x + moveX - startX), -this.wLimit), this.wLimit)
  80. this.translate.y = Math.min(Math.max((y + moveY - startY), -this.hLimit), this.hLimit)
  81. }
  82. let upHandle = () => {
  83. document.removeEventListener('touchmove', moveHandle, { passive: false })
  84. document.removeEventListener('touchend', upHandle)
  85. document.removeEventListener('mousemove', moveHandle, { passive: false })
  86. document.removeEventListener('mouseup', upHandle)
  87. }
  88. document.addEventListener('touchmove', moveHandle, { passive: false })
  89. document.addEventListener('touchend', upHandle)
  90. document.addEventListener('mousemove', moveHandle, { passive: false })
  91. document.addEventListener('mouseup', upHandle)
  92. },
  93. scrollFunc (e) {
  94. e = e || window.event
  95. let up = () => {
  96. this.tscale < MAXSCALE && (this.tscale += RANGE)
  97. }
  98. let down = () => {
  99. let scaleFuc = (y) => {
  100. this.translate = {
  101. x: 0,
  102. y
  103. }
  104. }
  105. this.tscale > MINSCALE && (this.tscale -= RANGE)
  106. this.ismobile ? (this.tscale === 3 && scaleFuc(184)) : (this.tscale === 1 && scaleFuc(0))
  107. }
  108. if (this.isFireFox) {
  109. switch (true) {
  110. case e.detail > 0: // 当滑轮向下滚动时
  111. down()
  112. break
  113. default:
  114. up()
  115. break
  116. }
  117. } else { // 判断浏览器IE,谷歌滑轮事件
  118. switch (true) {
  119. case e.wheelDelta > 0:// 当滑轮向上滚动时
  120. up()
  121. break
  122. default:
  123. down()
  124. break
  125. }
  126. }
  127. }
  128. },
  129. mounted () {
  130. var box = document.querySelector('#box')
  131. this.readyMove = this.readyMove.bind(this)
  132. this.$refs.layout.addEventListener('mousedown', this.readyMove, { capture: false })
  133. this.$refs.layout.addEventListener('touchstart', this.readyMove, { capture: false })
  134. /* IE、Opera注册事件 */
  135. if (document.attachEvent) {
  136. box.attachEvent('onmousewheel', this.scrollFunc)
  137. }
  138. // Firefox使用addEventListener添加滚轮事件
  139. if (document.addEventListener) { // firefox
  140. box.addEventListener('DOMMouseScroll', this.scrollFunc, false)
  141. }
  142. // Safari与Chrome属于同一类型
  143. window.onmousewheel = box.onmousewheel = this.scrollFunc
  144. var boxGesture = setGesture(box) // 得到一个对象
  145. boxGesture.gesturestart = function () { // 双指开始
  146. }
  147. boxGesture.gesturemove = () => { // 双指移动
  148. // let temp = this.tscale + e.dec
  149. // // this.tscale = Math.max(MINSCALE, Math.min(MAXSCALE, temp))
  150. // this.tscale = temp < MAXSCALE ? temp : MAXSCALE
  151. // this.tscale = temp > MINSCALE ? temp : MINSCALE
  152. }
  153. boxGesture.gestureend = function () { // 双指结束
  154. }
  155. },
  156. beforeDestroy () {
  157. this.$refs.layout.removeEventListener('mousedown', this.readyMove)
  158. this.$refs.layout.removeEventListener('touchstart', this.readyMove)
  159. }
  160. }
  161. </script>
  162. <style lang="less" scoped>
  163. .per-layout{
  164. width: 100%;
  165. height: 100%;
  166. touch-action:none;
  167. }
  168. .content{
  169. width: 120%;
  170. will-change: transform;
  171. position: relative;
  172. left: 50%;
  173. height: 100%;
  174. touch-action:none;
  175. }
  176. </style>