邃芒官网、邃芒慧影、口播(H5) https://m.metavatar.cc
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

282 lines
7.8 KiB

  1. <template>
  2. <div class="uploder">
  3. <div class="change-photo-setter">
  4. <van-uploader class="sett-item" :before-read="beforeRead">
  5. <div style="height: 100%"><img :src="ImgUrl" alt="" /></div>
  6. <img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" />
  7. </van-uploader>
  8. </div>
  9. <div class="uploadava">
  10. <van-popup
  11. duration="0"
  12. v-model="showCropper"
  13. position="top"
  14. :style="{ height: '100%' }"
  15. >
  16. <div class="cropper-container">
  17. <van-loading
  18. v-show="loadingShow"
  19. size="50"
  20. color="#fff"
  21. vertical
  22. text-color="#fff"
  23. >上传中...</van-loading
  24. >
  25. <vueCropper
  26. ref="cropper"
  27. :img="option.img"
  28. :outputSize="option.outputSize"
  29. :outputType="option.outputType"
  30. :info="option.info"
  31. :full="option.full"
  32. :autoCropWidth="option.autoCropWidth"
  33. :autoCropHeight="option.autoCropHeight"
  34. :canMove="option.canMove"
  35. :canMoveBox="option.canMoveBox"
  36. :original="option.original"
  37. :autoCrop="option.autoCrop"
  38. :fixed="option.fixed"
  39. :fixedNumber="option.fixedNumber"
  40. :centerBox="option.centerBox"
  41. :infoTrue="option.infoTrue"
  42. :fixedBox="option.fixedBox"
  43. :high="option.high"
  44. :mode="option.mode"
  45. />
  46. <van-nav-bar
  47. left-text="取消"
  48. right-text="确定"
  49. @click-left="onClickLeft"
  50. @click-right="onClickRight"
  51. />
  52. </div>
  53. </van-popup>
  54. </div>
  55. </div>
  56. </template>
  57. <script>
  58. import { awsImgUpload } from '@/api/editModel'
  59. import { Toast } from 'vant'
  60. import { VueCropper } from 'vue-cropper'
  61. export default {
  62. name: 'uploadAva',
  63. components: {
  64. VueCropper
  65. },
  66. props: {
  67. showAta: {
  68. default: false,
  69. type: Boolean
  70. },
  71. avaUrl: {
  72. default: '',
  73. type: String
  74. }
  75. },
  76. data() {
  77. return {
  78. ImgUrl: '',
  79. show: true, // 上传类型的弹窗
  80. imageFileName: '',
  81. showCropper: false, // 裁剪的弹窗
  82. option: {
  83. img: '',
  84. outputSize: 0.8,
  85. info: false, // 裁剪框的大小信息
  86. outputType: 'jpeg', // 裁剪生成图片的格式
  87. canScale: true, // 图片是否允许滚轮缩放
  88. autoCrop: true, // 是否默认生成截图框
  89. autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度
  90. autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度
  91. high: true, // 是否按照设备的dpr 输出等比例图片
  92. fixedBox: false, // 固定截图框大小 不允许改变
  93. fixed: true, // 是否开启截图框宽高固定比例
  94. fixedNumber: [1, 1], // 截图框的宽高比例
  95. full: true, // 是否输出原图比例的截图
  96. canMoveBox: true, // 截图框能否拖动
  97. original: false, // 上传图片按照原始比例渲染
  98. centerBox: true, // 截图框是否被限制在图片里面
  99. infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  100. mode: '100% auto' // 图片默认渲染方式
  101. },
  102. loadingShow: false // 是否展示loading
  103. }
  104. },
  105. methods: {
  106. beforeRead(file) {
  107. console.log(file)
  108. if (file.type !== 'image/jpeg' && file.type !== 'image/png') {
  109. this.$toast('请上传 jpg/png 格式图片')
  110. return false
  111. }
  112. let data = window.URL.createObjectURL(new Blob([file]))
  113. this.option.img = data //给裁剪图片的路径
  114. this.showCropper = true
  115. return false
  116. },
  117. // 点击裁剪的选择
  118. onClickRight() {
  119. let that = this
  120. this.loadingShow = true
  121. this.$refs.cropper.getCropBlob(async (data) => {
  122. let formData = new FormData()
  123. formData.append('file', data)
  124. let file = formData.get('file')
  125. // 转为 base64
  126. let reader = new FileReader()
  127. reader.onload = async () => {
  128. // base64结果
  129. that.ImgUrl = this.result
  130. that.loading = false
  131. }
  132. reader.readAsDataURL(file)
  133. // await that.toBase64(file)
  134. console.log(that.ImgUrl, 'dasdasd')
  135. // 发请求
  136. const AccessToken = localStorage.getItem('AccessToken')
  137. that
  138. .$axios({
  139. method: 'post',
  140. // url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`,
  141. url: `http://m.metavatar.cc/C/api/upload/awsImgUpload`,
  142. headers: {
  143. // 'Content-Type': 'application/json;charset=UTF-8',
  144. 'content-type': 'multipart/form-data',
  145. token: AccessToken,
  146. 'Access-Control-Allow-Credentials': true
  147. },
  148. data: { file: that.base64ToBinary(that.ImgUrl) }
  149. })
  150. .then((res) => {
  151. console.log(res)
  152. console.log(that.ImgUrl)
  153. console.log(that.base64ToBinary(that.ImgUrl))
  154. that.loadingShow = false
  155. that.showCropper = false
  156. Toast.success('上传成功')
  157. })
  158. })
  159. },
  160. // 点击取消
  161. onClickLeft() {
  162. this.loadingShow = false
  163. this.showCropper = false
  164. this.$parent.showPhotoUploader = false
  165. },
  166. // 上传图片
  167. async pushImg(data) {
  168. try {
  169. const res = await awsImgUpload(data)
  170. this.loadingShow = false
  171. this.showCropper = false
  172. Toast.success('上传成功')
  173. } catch (error) {
  174. console.log(error, 'error')
  175. Toast.fail(error.message)
  176. }
  177. },
  178. //图片转base64,异步
  179. toBase64(file) {
  180. let that = this
  181. return new Promise((resolve, reject) => {
  182. const reader = new FileReader()
  183. reader.onload = () => {
  184. // base64结果
  185. that.ImgUrl = this.result
  186. that.loading = false
  187. }
  188. reader.onerror = reject
  189. reader.readAsDataURL(file)
  190. })
  191. },
  192. // base64 转二进制
  193. base64ToBinary(base64) {
  194. console.log(base64)
  195. const binaryString = window.atob(base64)
  196. const binaryLength = binaryString.length
  197. const bytes = new Uint8Array(binaryLength)
  198. for (let i = 0; i < binaryLength; i++) {
  199. bytes[i] = binaryString.charCodeAt(i)
  200. }
  201. return bytes
  202. }
  203. }
  204. }
  205. </script>
  206. <style lang="scss" scoped>
  207. // .uploder{
  208. // overflow: hidden;
  209. // }
  210. /deep/.cropper-view-box {
  211. outline: 2px dashed #fff !important;
  212. }
  213. /deep/.crop-point {
  214. background-color: auto !important;
  215. }
  216. /deep/.van-loading {
  217. position: absolute;
  218. // color: red;
  219. z-index: 9999;
  220. left: 50%;
  221. top: 50%;
  222. margin-left: -55px;
  223. margin-top: -30px;
  224. background: rgba(0, 0, 0, 0.3);
  225. padding: 10px 30px;
  226. border-radius: 25px;
  227. }
  228. .uploadava {
  229. .update-avatar {
  230. height: 100%;
  231. text-align: center;
  232. .update-avatar-line {
  233. width: 100%;
  234. height: 1px;
  235. background-color: #979797;
  236. }
  237. .avatar-select-type {
  238. background-color: #fff;
  239. width: 346px;
  240. border-radius: 12px;
  241. padding-bottom: 4px;
  242. .upload-avator {
  243. padding: 14px;
  244. }
  245. }
  246. p {
  247. margin: 15px 0 30px;
  248. background-color: #fff;
  249. width: 346px;
  250. border-radius: 12px;
  251. padding: 15px 0 18px;
  252. }
  253. }
  254. .cropper-container {
  255. height: 94vh;
  256. .van-nav-bar {
  257. background-color: rgba(0, 0, 0, 0.87);
  258. :global(.van-nav-bar__text) {
  259. color: #fff;
  260. // font-size: $font-size-normal-x;
  261. }
  262. :global(.van-nav-bar__text:nth-child(2)) {
  263. color: #000;
  264. font-weight: 500;
  265. }
  266. // :global(.van-icon) {
  267. // color: red;
  268. // }
  269. }
  270. }
  271. .vue-cropper {
  272. background: #000;
  273. height: 100%;
  274. padding-top: 46px;
  275. box-sizing: border-box;
  276. }
  277. }
  278. </style>