短视频小程序坑 分享

常见问题

点赞 (帧动画)

  • 前言,需求要一个点赞动画 ,给了我48张 帧图

  • 初试: 使用 图片src 循环切换地址 来 ,很卡顿,完全不能达到 UI 的要求

  • 再试 小程序 canvas 支持 Canvas.requestAnimationFrame,来做帧动画,发现taro 1.3这个版本 获取 对象 为空 然后继续放弃

  • 再试: 使用css 动画来实现,也是最终方案

.icon-like{
            width:192px;height:192px;

            background: url('https://pubimg.xingren.com/969e96c6-baf7-4fea-8081-72980a24e00a.png') no-repeat; //总共16张小图,每个图的大小是192*192
            background-position: 0 0;
            transform: scale(0.65);
          }
          .animation{
            animation:heart-animated 0.64s 1 steps(15); //这里的steps,15的值是总共16图-1=15,是步长,因为初始就是第一张,所以这里是15
            animation-fill-mode: forwards; //动画完成后,保持最后一个属性值 ,backwards初始
          }
          @keyframes heart-animated {
            0%{background-position: left;}
            100%{background-position: right;}
          }


<View className="item" onClick={this.funLike}>
                  {curr.userPraised === 1? <View  className="item-animation-like"><View className="icon-like my-heart-animation"></View> </View>:''}
                  <Image   className="item-pic" src={pics.defLike} style={{display:curr && curr.userPraised === 1?'none':'inline-block'}}></Image>
                <View className="text">{curr.viewNumber}</View>
              </View>
loading ~ 


   .icon-loading {
      width: 112px;
      height: 112px;
      background: url('https://pubimg.xingren.com/8a52462a-67a3-4b9b-85ee-9de51036d4d7.png');
      //总共16张小图,每个图的大小是60*100 所以width: 60px;height: 100px;
      background-size: auto 100%;
      // transform: scale(0.5);
    }
    .loading-animation {
      animation: loading-animated 1.72s steps(43, end) infinite; //这里的steps,15的值是总共16图-1=15,是步长,因为初始就是第一张,所以这里是15
    }
    @keyframes loading-animated {
      0% {
        background-position: 0 0;
      }

      100% {
        background-position: -4300% 0;
      }
    }
 

图片切换为视频后有 按钮闪烁一下

解决方法 :主要是先播放 再隐藏(第一次)

setTimeout(()=>{
        this.videoContext.play();
        setTimeout(()=>{
          this.setData({
            showCover:false
          });
        },0.1*1000)
      },1*1000)

资源预加载

在使用前进行预加载 进行 处理

  在插件中进行页面处理

可视范围 按照流播放

  • 这里 不做代码 讲一下思路
  • (利用 Promise)(也可以 在单个视频中 使用 setTimeOut 来处理,但是缺点是 不能按顺序,销毁也不好控制,不推荐)
  • 得到 需要view 的高度合集
  • 循环 执行 集合中的展示
  • 注意: 在执行前需要传入 当前时间戳 ,来处理之前执行的代码,是否 继续执行(目的:按顺序流执行,之前未执行完的直接销毁)
 const $t = this;
    const playList: PlayList[] = [];
    const { windowHeight } = await Taro.getSystemInfoSync();
    const {networkType} = await new Promise(resolve => {
      Taro.getNetworkType({
        complete: function(res) {
          // @ts-ignore
          resolve(res);
        },
      });
    });
    if(networkType !== 'wifi') return;//非wifi 不做切换处理

    const getPlayIds = async (timeRun: number) => {
      playList.length = 0;
      const query = Taro.createSelectorQuery().in($t.$scope);
      // 创建节点查询器 query
      query.selectAll('.video-card').boundingClientRect();
      query.selectViewport().scrollOffset();
      let [list, { scrollHeight }] = await new Promise(resolve => {
        query.exec((res) => {
          resolve(res);
        });
      });
      if (scrollHeight === 0) scrollHeight = scrollHeight;
      list = list.sort((a, b) => a.top - b.top);
      list.forEach(c => {
        const { top, bottom, dataset } = c;
        const { id, time } = dataset;
        if (top >= 0 && bottom < (windowHeight)) {
          playList.push({ id: id, time: time });
        }
      });
      // 在主线程中进行控制
      const playFun = async ()=>{
        if(timeRun !== $t.time) return;
        const funChange = async (obj)=>{
          const { time, id } = obj;
          await new Promise(resolve => {
            setTimeout(()=>{
               setTimeout(()=>{eventBus.$emit('video-status', { id, play:true, time });}, 0);
              resolve();
            }, 300);
          });//开始展示
          await new Promise(resolve => {
            setTimeout(()=>{
              resolve();
            }, time*1000+300);

          });//结束暂时
        };

        for(let i=0, len = playList.length;i<len;i++){
          if(timeRun === $t.time) await funChange(playList[i]);;

        }
        if(timeRun === $t.time) await  playFun();
      };

      if(playList.length >0){
        playFun();
      }else{
        eventBus.$emit('video-status', { id:'', play:false });
      }
    };

    eventBus.$on('nextTick', () => {
      setTimeout(() => {
        $t.time = new Date().getTime();
        getPlayIds($t.time);
      }, 300);
    });

    // 监听滚动 滚动停止后进行处理 位置进行播放
    let now_scrollTop = 0;
    eventBus.$on('onScroll', function (data) {
      const { scrollTop } = data;
      now_scrollTop = scrollTop;
      const c = setTimeout(() => {
        if (now_scrollTop === scrollTop) {
          $t.time = new Date().getTime();
          getPlayIds($t.time);
        }
        clearTimeout(c);
      }, 500);
    });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值