H5

coderljw 2024-10-13 H5
  • Uni App
  • H5
大约 2 分钟

# 1. H5 调用百度地图 api 跨域

  • main.js

    import { VueJsonp } from 'vue-jsonp'
    Vue.use(VueJsonp)
    
    1
    2
  • 使用示例。

    this.$jsonp(
      `https://api.map.baidu.com/geoconv/v1/?coords=${dLon},${dLat}&from=1&to=5&ak=${BMAP_KEY}`
    ).then(console.log)
    
    1
    2
    3

# 2. 图片切割成 9 份

cutImg() {
  const render = (x, y, index) => {
    const canvas = document.createElement('canvas')
    canvas.width = uni.upx2px(225)
    canvas.height = uni.upx2px(225)
    const ctx = canvas.getContext('2d')
    const img = new Image()
    img.src = require('../static/5t5.jpg')
    img.setAttribute('crossOrigin', 'Anonymous')
    img.onload = () => {
      const width = img.width / 3
      ctx.drawImage(
        img,
        x * width,
        y * width,
        width,
        width,
        0,
        0,
        uni.upx2px(225),
        uni.upx2px(225)
      )
      this.preImages.push({
        src: canvas.toDataURL(),
        serial: index,
        show: true,
        top: 0,
        left: 0,
      })
    }
  }

  const ary = []
  Array(3)
    .fill(1)
    .map((_, y) =>
      Array(3)
        .fill(1)
        .map((_, x) => ary.push([x, y]))
    )
  ary.map((item, index) => render(item[0], item[1], index))
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 3. IOS 微信内置浏览器自动播放音频

import wx from 'weixin-js-sdk'

/**
 * @description: 加载背景音乐
 * @author: ljw
 */
loadAudio() {
  const audioContext = uni.createInnerAudioContext()
  const config = {
    autoplay: true,
    loop: true,
    src: require('./static/audio/How it Began.mp3'),
  }
  this.$store.commit('SET_AUDIO', Object.assign(audioContext, config))
  this.$store.commit('SET_AUDIO_PLAY', true)
  wx.config({})
  wx.ready(() => audioContext.play())
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 4. 文件切片上传

  • 因后端接口需要上个请求返回的字段(不能并发了...),故而使用了组合函数。
import { UploadVideo } from '@/api/profile'
import jsMd5 from 'js-md5'
import qs from 'qs'

// 文件切片
function section(file) {
  return new Promise((resolve, reject) => {
    let fileName = file.name.split('.').slice(0, -1).join('.'),
      ext = file.name.split('.').slice(-1)[0],
      chunkSize = 1024 * 1024 * 2,
      count = Math.ceil(file.size / chunkSize),
      n = 0,
      chunks = []
    const reader = new FileReader(file)
    reader.readAsArrayBuffer(file)
    reader.onload = _ => {
      const hashName = jsMd5(reader.result)
      while (n < count) {
        chunks.push({
          file: file.slice(n * chunkSize, (n + 1) * chunkSize),
          name: `${hashName}_${fileName}_${n + 1}.${ext}`,
        })
        n++
      }
      resolve({
        name: `${hashName}_${file.name}`,
        size: file.size,
        count,
        chunks,
      })
    }
    reader.onerror = _ => reject()
  })
}

// 组合函数
const composePromise =
  (...fns) =>
  (...args) =>
    fns.reduceRight(
      (sequence, fn) => sequence.then(result => fn(result)),
      Promise.resolve(fns.pop()(...args))
    )

export default {
  methods: {
    uploadVideo() {
      uni.chooseVideo({
        count: 1,
        sourceType: ['camera', 'album'],
        success: async res => {
          this.video = ''
          this.previewVideo = res.tempFilePath
          this.videoProgress = 0
          this.videoRemove = false
          const { name, size, count, chunks } = await section(res.tempFile)

          const promises = chunks.map(({ file }, index) => {
            const fm = new FormData()
            fm.set('file', file)
            return ({ new_upload_id, upload_key }) => {
              const queryParams = {
                file_size: size,
                total_index: count,
                index: index + 1,
                file_name: name,
                upload_id: new_upload_id,
                upload_key,
              }

              return new Promise(async (resolve, reject) => {
                const { data } = await UploadVideo(
                  qs.stringify(queryParams),
                  fm
                ).catch(_ => {
                  this.videoRemove = true
                  reject()
                })
                this.videoProgress = (((index + 1) / count) * 100) | 0
                resolve(data.response)
              })
            }
          })

          const { data } = await composePromise(...promises.reverse())({})
          $showToast('上传成功')
          this.video = data.response.src
          this.videoRemove = true
        },
      })
    },
  },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
以父之名
周杰伦.mp3