Weapp影视评分项目开发(08):Home 页 (swiper与渐变背景色的实现)

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

前言

本篇是 Home 页面实现的第2篇,主要介绍 swiper 的使用与跟随 swiper 变化的渐变背景色的实现,从这一篇开始,我们也将正式进入了 api 的对接流程。

本篇文章对应代码分支为:home-swiper

知识点

swiper的使用 自定义swiper指示点 渐变背景色的实现 16进制颜色值转RGB 对象解构 对象简写 CCS3 渐变 CSS3 过渡动画

效果预览

swiper.gif

一、获取 swiper 相关数据

在之前接口介绍的文章中,我们做过 home 页面接口的调用示例,我们将获取到的数据 setDatadata 中,主要代码如下:

// home/index.js
import { getIndex } from '../../api/api'; // 导入获取首页数据的接口,小程序只支持绝对路径

Page({
  data: {
    swiper: []  // 初始化默认值
  },
  onLoad() {
    this.getIndex(); // 首页数据
  },
  // 获取首页信息
  async getIndex() {
    const { code, data } = await getIndex(); // 此处使用了对象解构与 await
    if (code === 200) {
      const { swiper } = data; // 轮播图
      this.setData({
        swiper    // 此处使用了对象简写
      })
    }
  }
})

二、swiper 的实现

1. 轮播图的实现

与上一篇的自定义头部一样,我们在 home/components 目录下为 swiper 建一个 home-swiper 组件,swiper 实现轮播效果并不复杂,可以查看官方文档 swiper 或者本项目源码,这里主要说一下 bindchange 事件,如何使用它来实现自定义的面板指示点 indicator-dots 与变换的背景色。

<!-- home/components/home-swiper/index.wxml -->
<swiper 
  class="home-swiper" 
  autoplay
  circular
  bindchange="swiperChange"
>
  <swiper-item 
    class="swiper-item" 
    wx:for="{{swiper}}" 
    wx:key="id"
  >
    <image mode="aspectFill" class="slide-image" src="{{item.banner}}" />
  </swiper-item>
</swiper>

以上代码中最重要的就是 bindchange 事件,我们需要通过它获取 swipercurrent 值。

Component({
  data: {
    swiperIndex: 0  // swiper 的 current 值,该值为 swiper-item 元素的索引 
  },
  // 注意:小程序的组件 Component 是有 methods 属性的
  // 页面的 Page 没有
  methods: {
    swiperChange(e) {
      this.setData({
        swiperIndex: e.detail.current
      })
    }
  }
})

swiperIndex 的值是 swiper-item 的索引,从 0 开始

2. 自定义面板指示点

我们根据接口返回的 swiper 条数,循环出对应的指示点,使用绝对定位将其固定在 swiper 的下方:

<view class='swiper-indicator'>
  <text 
    class="dot {{index ==  swiperIndex ? 'is-active': ''}}" 
    wx:for="{{swiper}}" 
    wx:key="index"
  />
</view>

我们根据 swiperIndex 是否与当前索引相等,相等则给当前指示点添加选中的样式 is-active
用这种方式可以实现多种效果的指示点。

3. 背景色渐变

1) 实现背景元素占位

占位标签没有内容,只是为了显示背景色,isTop 值与上一篇的 home-header 一样,当页面滚动超过阈值,则将背景色通过添加 opacity: 0 属性进行视觉上的隐藏,backgroundStyleswiper current 对应的渐变背景色样式。

不使用 display: none 隐藏是为了显隐时背景色能有个过渡动画效果,使切换效果不生硬。

<view class="bgcolor {{ !isTop ? 'is-transparent': '' }}" style="{{ backgroundStyle }}"></view>

在原有的获取 current 值基础上增加了样式设置:

methods: {
  swiperChange(e) {
    const index = e ? e.detail.current : 0;  // 获取当前索引,为何要设置个默认值 0 ?后面会有解释
    const bgcolor = this.data.swiper[index].bgcolor; // 图片的相似颜色值又接口返回
    const bgcolorRgba = colorToRgba(bgcolor, 0); // colorToRgba 方法后面会有介绍,用于获取当前颜色的近似值

    this.setData({
      swiperIndex: index,
      backgroundStyle: `background-image: linear-gradient(${bgcolor}, ${bgcolorRgba})`
    })
  }
}
.bgcolor {
  z-index: -1;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  height: 700rpx;
  /* 过渡动画,防止背景色切换生硬 */ 
  transition: background-image 0.6s ease-in-out, opacity .6s ease-in-out; 

  &.is-transparent {
    opacity: 0;
  }
}
2) 获取图片平均色调

这个可能让大家失望了,平均色调是我通过 phpgd2 库图片处理获取的,原理是对图片逐像素点扫描,获取每个像素点的颜色值,累加后除以像素点个数,获取到的就是平均值。
本项目图片使用的七牛云存储也提供了方法可以直接获取图片的平均色调,有兴趣的可以了解下。

3) 渐变背景色的实现

背景颜色产生渐变的效果,这个前端可以实现,项目的 utils/color.js 里面封装了该方法,其原理是将传入的16进制颜色值,转为 rgb 格式,再添加一个 alpha 透明度,利用 CSS3 的渐变背景色,从上至下 alpha 值由 10 即可。

// utils/color.js
/**
 * @desc 16进制颜色转换为 RGBA 格式
 * @param {string} color 16进制颜色值
 * @param {float} [alpha=1] 透明度,范围 0-1  
 * @return {string} RGBA 格式颜色值
*/
export default (color, alpha) => {
  // 16进制颜色值的正则
  let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;

  // 把颜色值变成小写
  color = color.toLowerCase();

  if (reg.test(color)) {
    // 如果只有三位的值,需变成六位,如:#fff => #ffffff
    if (color.length === 4) {
      let colorNew = "#";
      for (let i = 1; i < 4; i += 1) {
        colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
      }
      color = colorNew;
    }

    // 处理六位的颜色值,转为RGB
    let colorChange = [];
    for (let i = 1; i < 7; i += 2) {
      colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
    }
    return `RGB(${colorChange.join(",")}, ${alpha})`;
  } else {
    return color;
  }
}

4. 初始化渐变色

以上代码,只有触发了 swiperChange 事件才会进行背景色设置,但 swiper 初始化后不会立即触发该事件,导致默认第一张图片时背景色是空的,所以我们需要监听 swiper 是否传入数据,当有数据时手动触发下swiperChange 事件,代码如下:

Component({
  properties: {
    swiper: {
      type: Array,
      // 监听 swiper 的变化,当接口返回数据后,swiper有数据时,我们调用 swiperChange 事件,
      // 因为手动调用没有 event,所以我们对该方法传参进行判断,如果未传则赋值 0
      observer(val) {
        if (val.length) {
          this.swiperChange();
        }
      }
    }
  },
  methods: {
    swiperChange(e) {
      const index = e ? e.detail.current : 0; // 在此判断是否存在 event,不存在则设置为 0
      // 设置背景色代码同上
    }
  }
})

最后

本篇文章主要介绍小程序中 swiper 的使用、自定义指示点的实现、以及渐变背景色的实现,下一篇,我们将完成首页的全部内容。
感谢阅读。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容