h5 js调用移动端 相机 相册

 效果:

点击从手机相机获取图片或打开相机拍摄图片,  触屏缩放移动 加载的图片到合适位置

h5 js调用移动端 相机 相册_第1张图片

注意这里的几个坑:

1  在红米K40上 出现了  微信浏览器点击,触发change事件后只能调到相册,无法弹出“相机或相册选择框”,而且无法选中相片的问题。

    参考  前段H5开发,小米上用input File 为什么获取不到照片的数据? - 知乎

解决方法如下代码。


          
          

只不过解决后因为问题2 又都注释掉了。

2  在ios系统上 出现了  第一次点击,经常无法触发change事件的情况

     具体现象:安卓手机上,微信浏览器、自带浏览器都没有问题。苹果手机上,第一次点击,有时候无法触发change事件(复现频率较高),第二次点击就好了。访问过一次,点击,好了后,刷新页面也不一定能复现问题。(坑死)
    参考  https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only

       解决方法:
        将initNew() 方法里下面这两行注释掉   

  // this.input = document.querySelector('#image_uploads')
        // this.input.addEventListener('change', this.updateImageDisplay)

        将 template 里的   元素注释掉  


          
          

        换成initNew() 方法里

// input 元素绑定 change 事件 
        let mobileCamera = document.querySelector('#mobileCamera')
        let input =  document.createElement("input"); 
        input = document.body.appendChild(input)
        input.type = "file"
        input.id = "image_uploads"
        input.className="inputFile";
        input.multiple= true
        input.accept="image/png,image/jpeg,image/gif"
        input.style.width=  "1%"
        input.style.height = "1%"
        input.style.position =  'absolute';
        input.style.opacity = 0;
        input.addEventListener('change', this.updateImageDisplay)

注意这里   

    input = document.body.appendChild(input)  ,绑定在 document.body 上,一开始绑定在 

上,未解决问题,至于绑定在其他dom上可以不,还未测试。

    绑定change事件用 ,input.addEventListener('change', this.updateImageDisplay)  

用onchange 未生效。

         

   

3  功能设计里,是用img 或者div点击后,去触发 input 元素的click事件的。而这种情况下,在ios系统上 出现了 img、div  需要双击的情况才能触发click,input 支持单击。  Android手机无此问题。
    参考  tap事件_苏醒!的博客-CSDN博客_tap事件

    解决方法 

        let mobileCamera = document.querySelector('#mobileCamera')
        // 用 tab 换掉 click ,click在ios safari浏览器上有 单击失效,需要双击  的问题
        this.bindTapEvent(mobileCamera,(e)=>{
          input.click();
        })


       bindTapEvent(dom,callback){
            var startTime = 0;
            var isMove = false;
            dom.addEventListener('touchstart',function(){
              startTime = Date.now();
              console.log(startTime);
            });
            dom.addEventListener('touchmove',function(){
              isMove = true;
            });
            dom.addEventListener('touchend',function(e){
              console.log(Date.now()-startTime);
              if((Date.now()-startTime)<250&&isMove == false){
                callback&&callback.call(this,e)
              }else{
            console.log('失败');
              }
              isMove = false;
              startTime = 0;
            });
      },

直接上代码


import Hammer from 'hammerjs'
import axios from 'axios'

 export default {
    name: 'conponent01',
    props: {
  
    },
    computed: {},
    data () {
      return {

        input: undefined,
        src: "",
        show1:false,
        show:true,
        loading:false,

        // 拖动缩放
        imgScale: 1,
        oldScale: 1,
        imgPos: {
          x: 0,
          y: 0
        },

      }
    },
    mounted () {
  
      // 图片操作 移动 缩放
      this.zoom()
      
      this.initNew()
    },
  
    methods: {
      // 同事写的   移动端 移动、缩放元素
      zoom(){
        var square = this.$el.querySelector('#mobileCameraPreview')
          let that = this
          // Create an instance of Hammer with the reference.
          var hammer = new Hammer(square)
          hammer.get('pinch').set({ enable: true })
          // Subscribe to a quick start event: press, tap, or doubletap.
          // For a full list of quick start events, read the documentation.
          hammer.on('panend', function (e) {
            that.imgPos.x += e.deltaX
            that.imgPos.y += e.deltaY
          })
          hammer.on('pan', function (e) {
            // console.log('pan=====', e)
            square.style.transform = `matrix(${that.imgScale},0,0,${that.imgScale},${that.imgPos.x + e.deltaX},${that.imgPos.y + e.deltaY})`
          })
          hammer.on('pinch', function (e) {
            that.imgScale = Math.max(Math.min(that.oldScale * e.scale, 10), 1)
            square.style.transform = `matrix(${that.imgScale},0,0,${that.imgScale},${that.imgPos.x},${that.imgPos.y})`
          })
          hammer.on('pinchend', function (e) {
            that.oldScale = that.imgScale
          })
      },
 
      

      initNew () {
        // input 元素绑定 change 事件 
        let mobileCamera = document.querySelector('#mobileCamera')
        let input =  document.createElement("input"); 
        input = document.body.appendChild(input)
        input.type = "file"
        input.id = "image_uploads"
        input.className="inputFile";
        input.multiple= true
        input.accept="image/png,image/jpeg,image/gif"
        input.style.width=  "1%"
        input.style.height = "1%"
        input.style.position =  'absolute';
        input.style.opacity = 0;
        input.addEventListener('change', this.updateImageDisplay)
        
         //  在ios系统上 出现了  第一次点击,经常无法触发change事件的情况
         // 参考  https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only
        //  将下面这两行  和  template 里的   元素注释掉  换成上面这个 createElement('input')  
        // this.input = document.querySelector('#image_uploads')
        // this.input.addEventListener('change', this.updateImageDisplay)
        // 用 tab 换掉 click ,click在ios safari浏览器上有 单击失效,需要双击  的问题
        this.bindTapEvent(mobileCamera,(e)=>{
          input.click();
        })
      },
      // 参考 https://blog.csdn.net/qq_42309685/article/details/102526869
      bindTapEvent(dom,callback){
        var startTime = 0;
        var isMove = false;
        dom.addEventListener('touchstart',function(){
          startTime = Date.now();
          console.log(startTime);
        });
        dom.addEventListener('touchmove',function(){
          isMove = true;
        });
        dom.addEventListener('touchend',function(e){
          console.log(Date.now()-startTime);
          if((Date.now()-startTime)<250&&isMove == false){
            callback&&callback.call(this,e)
          }else{
            console.log('失败');
          }
          isMove = false;
          startTime = 0;
        });
      },
      imgClick () {
        this.input.click();
      },
      updateImageDisplay () {
        let _this = this
        this.loading = true
        
        const curFiles = this.input.files
        if (curFiles.length === 0) {
          // no file
        } else {
          for (const file of curFiles) {
            // 方法1  上传后台  返回服务器端图片地址 赋值给 src
            var formData = new FormData()
            formData.append('files',file)
            axios({
                  method: 'post',
                  url: 'https://xxxxxx/api/ossupload/uploadFile',
                  data: formData
            }).then((res)=>{
              console.log(res.data.data[0].path)
              _this.show1 = true
              _this.show = false
              _this.$nextTick(()=>{
                _this.src = res.data.data[0].path
                _this.loading = false

                // 图片操作相关
                _this.imgScale = 1
                _this.oldScale = 1
                _this.imgPos = {
                  x: 0,
                  y: 0
                }
                _this.$el.querySelector('#mobileCameraPreview').style.transform = `matrix(1,0,0,1,0,0)`
              })
            })

            // 方法2  读成 base64 赋值给 src
            // var reader = new FileReader()
            // reader.readAsDataURL(file)
            // reader.onload = function () {
            //   _this.show1 = true
            //   _this.show = false
            //   _this.$nextTick(()=>{
            //     _this.src = this.result
            //     _this.imgScale = 1
            //     _this.oldScale = 1
            //     _this.imgPos = {
            //       x: 0,
            //       y: 0
            //     }
            //     _this.$el.querySelector('#mobileCameraPreview').style.transform = `matrix(1,0,0,1,0,0)`
            //   })
            // }
          }
        }
      },
  
  
    },

  }



 

你可能感兴趣的:(javascript,前端,vue.js)