H5+ vue开发app 问题记录

本文介绍如何在HBuilderX中设置沉浸式状态栏的文本颜色,并实现图片的缓存、预览、缩放、移动及保存到相册的功能。通过在plus配置中添加statusbar设置,可以轻松实现状态栏的文字颜色调整。同时,提供了详细的代码示例,用于缓存图片到本地并进行各种交互操作。
摘要由CSDN通过智能技术生成

1、设置沉浸式状态栏,文字样式

在"plus"下添加下面设置

"statusbar": {  /* 设置沉浸式状态栏*/
                "immersed": true  
        }, 

可以给默认全局文字样式,在true的后面加逗号 添加style,目前只支持两种颜色,dark和light,黑和白,其他的兼容性不好:如下

"style":"dark"// 状态栏文字颜色,默认黑色

2、缓存图片到本地,实现图片预览,缩放,移动,保存到相册

首先缓存图片,在用户点击的图片时把图片缓存到 _doc/下

openDownload(url,num){
        // this.$reduction(url)
        // this.$toast('/storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/hz/hz1578880307463.jpg')
        this.downloadFile(url,num)
      },
      downloadFile(url,num){// 下载文件
        let _this = this;
        let filename = url.substring(url.lastIndexOf('/')+1,url.length);
        this.plusReady(()=>{
          //判断文件是否已经下载
          plus.io.resolveLocalFileSystemURL(
            '_doc/hz/' + filename,
            function (entry) {//如果已存在文件,则打开文件
              if (entry.isFile) {
                if(num === 1){// 图片
                  let path = plus.io.convertLocalFileSystemURL('_doc/hz/' + filename);
                  console.log('path:::::'+ path);
                  _this.$reduction(path);
                }
                else plus.runtime.openFile('_doc/hz/' + filename);// 图片以外的文件
              }
            }, function () {//如果未下载文件,则下载后打开文件
              var dtask = plus.downloader.createDownload(url, { filename: '_doc/hz/' + filename }, function (d, status) {
                if (status === 200) {
                  if(num === 1){// 图片
                    let path = plus.io.convertLocalFileSystemURL('_doc/hz/' + filename);
                    console.log('path:::::'+ path);
                    _this.$reduction(path);
                  }
                  else plus.runtime.openFile('_doc/hz/' + filename);
                }
                else {
                  _this.$toast("文件打开失败");
                  dtask.abort();// 下载失败,取消下载任务
                }
              });
              dtask.addEventListener("statechanged", function (task, status) {
                if (!dtask) { return; }
                switch (task.state) {
                  case 1:
                    break;
                  case 2:
                    break;
                  case 3: // 已接收到数据
                    // _this.$progressBar({amountSize:task.totalSize,loadSize:task.downloadedSize});
                    break;
                  case 4:
                    dtask = null;
                    break;
                }
              });
              dtask.start();
            }
          );
        })
      },

如果是图片则调用图片预览组件,否则就调用系统其他工具打开文件。$reduction的代码如下:

//引用模板文件
import reduction from './imgReduction1.vue';
//新建一个对象,用来保存实例
let obj = {};
//删除dom元素
let removeDom = (el) => {
  el.parentNode.removeChild(el);
};
obj.install = function (Vue) {
  const ToastController = Vue.extend(reduction);
  // 实现toast的关闭方法
  ToastController.prototype.close = function () {
    removeDom(this.$el);
  };
  // 在Vue的原型上实现reduction的挂载以及功能实现
  // 用户可以再Vue实例通过this.$reduction来访问以下的内容
  Vue.prototype.$reduction = (option = {}) => {
    //toast实例挂在到刚创建的Div
    let instance = new ToastController().$mount(document.createElement('div'));
    // 用户可以设置src属性也可以不设置,不设置时:则直接将option的内容作为src
    instance.src = option.src || option;
    // 将元素挂在到DOM上
    document.body.appendChild(instance.$el);
    //实现自动关闭
    // setTimeout(function () {
    //   instance.close();
    // }, instance.duration)
  }
};
export default obj;
<template>
  <!-- 为了解决 ios 的fixed 问题,采用旧的支持调用当前组件的方式图片放大模式会导致 div高度被覆盖无法解决,所以把div挂载在dom根节点body上 -->
  <div class="imgReduction" @click="imgClick($event)">
    <img :src="src"
         @touchstart="touchStart1($event)"
         @touchend="touchEnd1($event)"
         title="点击阴影部分关闭"/>
    <!--:style="{transform:'scale('+scale +')',webkitTransform:'scale('+scale +')','left':left,'top':top}"-->
    <!--:class="elementScale"-->
    <!--@mousewheel="bigImg($event)"-->
    <!--@touchstart="touchStart($event)"-->
    <!--@touchmove="touchMove($event)"-->
    <!--@touchend="touchEnd($event)"-->
    <!--@dblclick.stop="dbclick($event)"-->
  </div>
</template>

<script>
  export default {
    name: 'img-reduction1',
    props:{
      src:{type:String,default:''},// 展示的图片路劲
    },
    data(){
      return{
        isShow:false,
        url:'',// 要放大的图片路径
        pageX:'',
        pageY:'',
        initX:'',
        initY:'',
        isTouch:false,
        start:[],
        scale:'',
        left:'',
        top:'',
        time:null,
      }
    },
    computed:{
      // elementScale(){
        // return{
        //   'aaa':
        //   '{transform: scale(2,4);\n' +
        //   '-ms-transform: scale(2,4);\n' +
        //   '-webkit-transform: scale(2,4);\n' +
        //   '-o-transform: scale(2,4);\n' +
        //   '-moz-transform: scale(2,4);}'
        // }
      // }
    },
    methods:{
      touchStart1(e){
        this.startTime = new Date().getTime();
      },
      touchEnd1(e){
        let _this = this;
        let endTime = new Date().getTime();
        if(endTime - _this.startTime > 1000){
          _this.$confirm({message:'<span style="font-size: 0.32rem">保存图片</span>'}).then(res=>{
            res &&
            this.plusReady(()=>{
              console.log(_this.src)
              plus.gallery.save( _this.src,
                function (event) {
                  // console.log(event.path);
                  _this.$toast('图片已保存,请到相册查看');
                }, function () {
                  _this.$toast('图片保存失败');
                });
            })
          })
        }
      },


      /**
       * 浏览器鼠标缩放功能
       * */
      bigImg(event){
        let width = event.currentTarget.width;
        if(event.wheelDelta > 0){
          event.currentTarget.style.width = width + 15 + 'px'
        }else{
          event.currentTarget.style.width = width - 15 + 'px'
        }
      },
      imgClick(event){
        if(event.target.nodeName === 'DIV'){
          this.close();
        }
      },

      /**
       *
       * @param e
       * 移动端的缩放功能
       */
      touchStart(e){
        //手指按下时的手指所在的X,Y坐标  
        this.pageX = e.targetTouches[0].pageX;
        this.pageY = e.targetTouches[0].pageY;
        //初始位置的X,Y 坐标  
        this.initX = e.target.offsetLeft;
        this.initY = e.target.offsetTop;
        // alert(this.pageX+','+this.pageY+','+this.initX+','+this.initY)
        //记录初始 一组数据 作为缩放使用
        if (e.touches.length >= 2) { //判断是否有两个点在屏幕上
          this.start = e.touches; //得到第一组两个点
        }
        //表示手指已按下  
        this.isTouch = true;
        // 获取图片的初始坐标值
        this.x = e.target.x - e.target.offsetWidth,this.y = (document.body.clientHeight - e.target.offsetHeight)/2;
      },
      touchMove(e){
        e.preventDefault();
        // 一根 手指 执行 目标元素移动 操作
        if (e.touches.length === 1 && this.isTouch) {
          //移动目标的 X Y 坐标
          let touchMoveX = e.targetTouches[0].pageX,
            touchMoveY = e.targetTouches[0].pageY;
          //设置当前点击元素的 top left 定位值
          let left = parseInt(touchMoveX) - parseInt(this.pageX) + parseInt(this.initX),
            top = parseInt(touchMoveY) - parseInt(this.pageY) + parseInt(this.initY);
          // if(this.getOs().name === 'Iphone' || this.getOs().name === 'Mac') e.target.setAttribute('style','left:'+ left + 'px;top:'+top+'px');
          // else {
          //   e.target.style.left = left + "px";
          //   e.target.style.top = top + "px";
          // }
          this.left = left +'px';
          this.top = top + 'px';
        }
        // 2 根 手指执行 目标元素放大操作
        if (e.touches.length >= 2 && this.isTouch) {
          // this.$toast(this.y)
          /**
           * 由于img标签本身已经采用了相对定位,并且采用上下左右居中布局,
           * 所以导致在执行双指缩放操作时,获取到的初始left和top为50%,导致移动事件发生时会使img相对定位位置发生改变
           * 重新赋值
           * @type {string}
           */
          // if(this.getOs().name === 'Iphone' || this.getOs() === 'Mac') e.target.setAttribute('style','left:0;top:'+this.y+'px');
          // else {
          //   e.target.style.left =  "0";
          //   e.target.style.top = this.y + 'px';
          // }
          this.left = '0';
          this.top = this.y + 'px';
          this.$toast(this.left+','+this.top)
          //得到第二组两个点
          let now = e.touches;
          //得到缩放比例, getDistance 是勾股定理的一个方法
          let scale = (this.getDistance(now[0], now[1]) / this.getDistance(this.start[0], this.start[1]));
          // 对缩放 比例 取整
          e.scale = scale.toFixed(2);
          // this.$toast(e.scale)
          // 执行目标元素的缩放操作
          if(e.scale >= 2.5 || e.scale <= 0.5)return;
          // if(this.getOs().name === 'Iphone' || this.getOs() === 'Mac')e.target.setAttribute('style','transform:scale('+scale+')');
          // else e.target.style.transform = "scale(" + scale + ")";
          // e.target.style.transform = "scale(" + scale + ")";
          // e.target.style['transform'] = "scale(" + scale + ")";
          this.scale = scale;

        }
      },
      touchEnd(e){
        //将 isTouch 修改为false  表示 手指已经离开屏幕
        if (this.isTouch) {
          this.isTouch = false;
        }
      },
      getDistance(p1, p2) {
        var x = p2.pageX - p1.pageX,
          y = p2.pageY - p1.pageY;
        return Math.sqrt((x * x) + (y * y));
      },
      dbclick(e){// 双击事件,缩放为原始比例值
        // if(this.getOs().name === 'Iphone' || this.getOs() === 'Mac') e.target.setAttribute('style','left:0;top:'+this.y+'px');
        // else {
        //   e.target.style.left =  "0";
        //   e.target.style.top = this.y + 'px';
        // }
        this.left = '0';
        this.top = this.y + 'px';
        if(this.scale !==1){// 当放大倍数不等于1时,双击后缩放为原始比例
          // if(this.getOs().name === 'Iphone' || this.getOs() === 'Mac')e.target.setAttribute('style','transform:scale('+1+')');
          // else e.target.style.transform = "scale(" + 1 + ")";
          this.scale = 1;
        }else{// 当为原始比例1时,双击放到最大比例
          // if(this.getOs().name === 'Iphone' || this.getOs() === 'Mac')e.target.setAttribute('style','transform:scale('+2.5+')');
          // else e.target.style.transform = "scale(" + 2.5 + ")";
          this.scale = 2.5;
        }
      },
    }
  }
</script>

<style scoped>
  .imgReduction{
    position:fixed;
    background-color: rgba(0,0,0,0.6);
    width: 100%;
    height: 100%;
    left: 50%;
    top: 50%;
    -webkit-transform: translate(-50%,-50%);
    -moz-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    -o-transform: translate(-50%,-50%);
    transform: translate(-50%,-50%);
    z-index: 999999;
  }
  .imgReduction img{
    position: fixed;
    width: 100%;
    left: 50%;
    top: 50%;
    -webkit-transform: translate(-50%,-50%);
    -moz-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    -o-transform: translate(-50%,-50%);
    transform: translate(-50%,-50%);
    max-width:16rem !important;
    max-height:90% !important;
    min-height:50% !important;
  }
</style>

以上把注释掉的事件放入img标签中 可以支持在pc端鼠标的滚动缩放,按下移动,在手机安卓端支持单指移动,双指缩放,

但是操蛋的ios 不支持 style scale的设置,水平有限找不到方法兼容ios,所以只能放弃了,目前就支持长按保存到相册,谁有方法请留言,谢谢

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>