ImageCropper.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <popup v-if="src">
  3. <div class="com-image-cropper">
  4. <header app-border dir-bottom>
  5. {{title}}
  6. <i class="iconfont icon-close" @click="onClose"></i>
  7. </header>
  8. <div>
  9. <vue-cropper
  10. ref="cropper"
  11. alt="图片"
  12. :src="src"
  13. :view-mode="0"
  14. :aspect-ratio="options.aspectRatio || 1"
  15. :ready="ready"
  16. :min-container-width="(options.minContainerSize && options.minContainerSize.width) || null"
  17. :min-container-height="(options.minContainerSize && options.minContainerSize.height) || null"
  18. :container-style="options.containerStyle || containerStyle"
  19. ></vue-cropper>
  20. </div>
  21. <footer>
  22. <button class="ui-button submit" style="width:120px" @click="cropImage" :class="{disable:isCroping}">确定</button>
  23. <button class="ui-button cancel" style="width:120px" @click="onClose">取消</button>
  24. </footer>
  25. </div>
  26. </popup>
  27. </template>
  28. <script>
  29. import "cropperjs/dist/cropper.css";
  30. import VueCropper from "vue-cropperjs";
  31. import Popup from "./popup";
  32. import { base64ToDataURL, base64ToBlob } from "@/utils/file";
  33. import CompressImg from "@/utils/CompressImg";
  34. export default {
  35. name: "com-image-cropper",
  36. components: { Popup, VueCropper },
  37. props: {
  38. src: String,
  39. radius: Number,
  40. title: {
  41. type: String,
  42. default: ""
  43. },
  44. options: {
  45. type: Object,
  46. default() {
  47. return {};
  48. }
  49. },
  50. compress: Boolean,
  51. containerStyle: { height: "300px" }
  52. },
  53. data(){
  54. return{
  55. isCroping:false
  56. }
  57. },
  58. watch: {
  59. src(newVal, oldVal) {
  60. if (!newVal && oldVal) {
  61. this.$refs.cropper.destroy();
  62. }
  63. }
  64. },
  65. methods: {
  66. ready() {
  67. if (this.radius > 0) {
  68. this.$el.querySelector(".cropper-view-box").style.borderRadius =
  69. this.radius + "%";
  70. }
  71. },
  72. cropImage() {
  73. this.isCroping = true
  74. let base64 = this.$refs.cropper.getCroppedCanvas().toDataURL();
  75. this.dataURL && window.URL.revokeObjectURL(this.dataURL);
  76. if (this.compress) {
  77. const img = new Image();
  78. img.src = base64;
  79. img.onload = () => {
  80. const blob = base64ToBlob(base64);
  81. const simg = CompressImg(img, {
  82. weight: blob.size,
  83. maxWeight: 0.4 * 1024 * 1024,
  84. maxSize: 200
  85. });
  86. this.dataURL = simg.src;
  87. this.$emit("crop-blob", this.dataURL, simg.base64Src);
  88. this.onClose();
  89. };
  90. } else {
  91. this.dataURL = base64ToDataURL(base64);
  92. this.$emit("crop-blob", this.dataURL, base64);
  93. this.onClose();
  94. }
  95. },
  96. onClose() {
  97. this.isCroping = false
  98. this.$emit("close");
  99. }
  100. }
  101. };
  102. </script>
  103. <style lang="less" scoped>
  104. .com-image-cropper {
  105. width: 600px;
  106. min-width: 600px;
  107. background-color: #262729;
  108. font-size: 14px;
  109. color: #fff;
  110. overflow: hidden;
  111. border-radius: 9px;
  112. box-shadow: 0 0px 35px rgba(0, 0, 0, 0.3);
  113. header {
  114. padding: 10px 16px;
  115. height: 40px;
  116. i {
  117. float: right;
  118. cursor: pointer;
  119. }
  120. }
  121. footer {
  122. display: flex;
  123. align-items: center;
  124. justify-content: center;
  125. height: 80px;
  126. button {
  127. margin: 0 10px;
  128. }
  129. }
  130. > div {
  131. padding: 30px;
  132. padding-bottom: 0;
  133. display: flex;
  134. align-items: center;
  135. justify-content: center;
  136. }
  137. }
  138. </style>
  139. <style lang="less">
  140. .cropper-view-box {
  141. border: 1px solid rgba(2, 200, 174, 0.54);
  142. outline: 1px solid @color !important;
  143. outline-color: rgba(2, 200, 174, 0.75) !important;
  144. }
  145. .cropper-point {
  146. background-color: @color !important;
  147. }
  148. </style>