Weapp影视评分项目开发(09):Home 页 (swiper与渐变背景色的实现)
前言
本篇是 Home 页面实现的第2篇,主要介绍 swiper
的使用与跟随 swiper
变化的渐变背景色的实现,从这一篇开始,我们也将正式进入了 api
的对接流程。
本篇文章对应代码分支为:home-swiper
知识点
swiper的使用
自定义swiper指示点
渐变背景色的实现
16进制颜色值转RGB
对象解构
对象简写
CCS3 渐变
CSS3 过渡动画
效果预览
一、获取 swiper 相关数据
在之前接口介绍的文章中,我们做过 home
页面接口的调用示例,我们将获取到的数据 setData
到 data
中,主要代码如下:
// 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
事件,我们需要通过它获取 swiper
的 current
值。
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
属性进行视觉上的隐藏,backgroundStyle
是 swiper 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) 获取图片平均色调
这个可能让大家失望了,平均色调是我通过 php
的 gd2
库图片处理获取的,原理是对图片逐像素点扫描,获取每个像素点的颜色值,累加后除以像素点个数,获取到的就是平均值。
本项目图片使用的七牛云存储也提供了方法可以直接获取图片的平均色调,有兴趣的可以了解下。
3) 渐变背景色的实现
背景颜色产生渐变的效果,这个前端可以实现,项目的 utils/color.js
里面封装了该方法,其原理是将传入的16进制颜色值,转为 rgb
格式,再添加一个 alpha
透明度,利用 CSS3
的渐变背景色,从上至下 alpha
值由 1
到 0
即可。
// 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
的使用、自定义指示点的实现、以及渐变背景色的实现,下一篇,我们将完成首页的全部内容。
感谢阅读。
转载自:https://juejin.cn/post/7173661345655554078