功能一览

  • 图片缩放
  • 图片旋转
  • 图片拖拽

组件使用 vue 编写,可直接使用:

  1. <ImagePreview
  2. :src="previewSrc"
  3. :show.sync="previewShow"
  4. />
  1. <template>
  2. <div
  3. class="image-preview"
  4. v-if="show"
  5. @mousewheel.prevent="scaleImg"
  6. @mouseup="onMouseUp"
  7. @mousemove="move"
  8. >
  9. <div class="image-preview__mask" @click="hide" />
  10. <img
  11. class="image-preview__img"
  12. :src="src"
  13. :style="imgStyle"
  14. @dragstart.prevent
  15. @mousedown="onMouseDown"
  16. >
  17. <div class="image-preview__option">
  18. <a @click.stop="rotate(1)" @mouseup.stop><img src="https://img1.dxycdn.com/2018/1122/584/3313301195686592508-2.png"></a>
  19. <a @click.stop="rotate(2)" @mouseup.stop><img src="https://img1.dxycdn.com/2018/1122/118/3313301195686709591-2.png"></a>
  20. </div>
  21. </div>
  22. </template>
  23. <script>
  24. export default {
  25. name: 'ImagePreview',
  26. props: {
  27. show: {
  28. type: Boolean,
  29. default: false
  30. },
  31. src: {
  32. type: String,
  33. default: ''
  34. }
  35. },
  36. data () {
  37. return {
  38. scale: 0,
  39. startX: 0,
  40. startY: 0,
  41. moveX: 0,
  42. moveY: 0,
  43. x: 0,
  44. y: 0,
  45. angle: 0,
  46. onMove: false
  47. }
  48. },
  49. computed: {
  50. imgStyle () {
  51. return {
  52. transform: `scale(${1 + this.scale * 0.1}) rotate(${this.angle}deg)`,
  53. top: `${this.moveY || this.y}px`,
  54. left: `${this.moveX || this.x}px`,
  55. cursor: this.onMove ? 'grabbing' : 'grab'
  56. }
  57. }
  58. },
  59. watch: {
  60. 'show' (newVal) {
  61. if (!newVal) {
  62. this.scale = 0
  63. this.startX = 0
  64. this.startY = 0
  65. this.x = 0
  66. this.y = 0
  67. this.onMove = false
  68. }
  69. }
  70. },
  71. methods: {
  72. hide () {
  73. this.$emit('update:show', false)
  74. },
  75. scaleImg (e) {
  76. if (e.deltaY < 0) {
  77. this.scale += 1
  78. } else if (this.scale > -9) {
  79. this.scale -= 1
  80. }
  81. },
  82. onMouseDown (e) {
  83. if (e.button !== 0) return
  84. this.onMove = true
  85. this.startX = e.clientX
  86. this.startY = e.clientY
  87. return false
  88. },
  89. onMouseUp () {
  90. this.onMove = false
  91. if (this.moveX === 0 && this.moveY === 0) return
  92. this.x = this.moveX
  93. this.y = this.moveY
  94. this.moveX = 0
  95. this.moveY = 0
  96. },
  97. move (e) {
  98. if (this.onMove) {
  99. this.moveX = this.x + e.clientX - this.startX
  100. this.moveY = this.y + e.clientY - this.startY
  101. }
  102. },
  103. rotate (direct) {
  104. if (direct === 1) {
  105. this.angle -= 90
  106. } else {
  107. this.angle += 90
  108. }
  109. }
  110. }
  111. }
  112. </script>
  113. <style lang="less" scoped>
  114. .image-preview {
  115. position: fixed;
  116. top: 0;
  117. right: 0;
  118. bottom: 0;
  119. left: 0;
  120. z-index: 3000;
  121. text-align: center;
  122. &__mask {
  123. position: absolute;
  124. width: 100%;
  125. height: 100%;
  126. background: rgba(0, 0, 0, 0.75);
  127. cursor: url('~@/assets/images/close2.png'),auto;
  128. }
  129. &__img {
  130. position: relative;
  131. max-width: 100%;
  132. max-height: 100%;
  133. transition: transform 0.2s;
  134. }
  135. &__option {
  136. background: rgba(0, 0, 0, 0.349);
  137. position: fixed;
  138. height: 70px;
  139. padding:5px 0;
  140. bottom:0;
  141. left:0;
  142. width: 100%;
  143. text-align: center;
  144. a {
  145. display:inline-block;
  146. line-height: 0;
  147. border-radius: 3px;
  148. &:hover{
  149. background: rgba(255, 255, 255, 0.3);
  150. }
  151. img {
  152. max-width: 70px;
  153. max-height: 70px;
  154. will-change: transform;
  155. }
  156. }
  157. }
  158. }
  159. </style>

代码来自 dxyer