网易音乐版轮播-react组件版本

贾赦
• 阅读 3024

说明:

此版本轮播图为仿照网易云音乐PC播放器上首页的轮播。

网易的轮播特殊的地方就在于,如果你滑动不相邻的两张图片,其过渡效果并不是滑动过渡,而是一个跳出过渡,此方面原理与最开始设计轮播排版时候有极大关联。

网易音乐版轮播-react组件版本

此轮播为纯react环境下的es6写法,通过对state中数组的重组排列,配合样式。达到轮播的效果

无任何依赖,最终效果为封装成react组件开放接口并发布出去

注:此文章为正推,并在开发完成后进行总结优化。

一、搭建架构

此方面的文章应该很多,我就不必过多介绍,去github上找个react脚手架搭建一下基本项目框架即可。

我用的框架为改良过的一版本dva框架。react脚手架,github上很多,推荐自己选择一款进行改良,我用的并不一定适合你。

二、准备材料

1.大于4张尺寸相同图片。(本人为八张图片命名1-8)
2.react环境
3.网易云PC播放器

三、开发

先把首张图片和左右两侧能看见的图片位置摆好,
最开始的静态结构是这个样子的
新手注意:如发现代码刺眼,less、es6语法自行恶补

import React from 'react';

import styles from './Slide.less';

class Slide extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dir: [
        { name: 'middle' },
        { name: 'start' },
        { name: 'normal' },
        { name: 'normal' },
        { name: 'normal' },
        { name: 'normal' },
        { name: 'normal' },
        { name: 'end' },
      ],
    };
  }
  render() {
    const { dir } = this.state;
    return (
      <div key={key} className={styles.root}>
        {/* 外部容器*/}
        <div className={styles.slideBox}>
          {/* 内部循环*/}
          {
            dir.map((item, key) => {
              return (
                <div className={`${styles.slide} ${styles[item.name]}`}> // 此处偷懒
                  <img src={`./images/${key + 1}.png`} // 此处偷懒 alt="./images/404.png" />
                  <div // 蒙板
                    className={styles.masking}
                  >{''}</div>
                </div>
              );
            })
          }
        </div>
      </div>
    );
  }
}

export default Slide;

less如下

.root{
  width: 100%;
  background: #ccc;
  .slideBox{
    width: 50%;
    height: 15vw;
    margin: 0 auto;
    position: relative;
    background: #ccc;
    .slide{
      position: absolute;
      img{
        width: 100%;
      }
      .masking{ // 蒙板,有个灰度渐变的效果
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, .15);
      }
      &.middle{ // 此为中间展示的那张
        left: 10%;
        bottom: 0%;
        width: 80%;
        z-index: 33;
      }
      &.start{ // 第一张则为左侧那张
        left: 0%;
        bottom: 0%;
        width: 75%;
        z-index: 22;
        }
      &.end{ // 最后一张及右侧那张
        right: 0%;
        bottom: 0%;
        width: 75%;
        z-index: 22;
      }
      &.normal{ // 此为隐藏图片的样式
        left: 13%;
        bottom: 0%;
        width: 74%;
        z-index: 11;
      }
    }
  }
}

这样最开始的位置就摆好了。
网易音乐版轮播-react组件版本
隐藏图片的位置很重要,因为上面也说了,跨图片滑动时需要改成跳出效果。大概在如下位置,展示的那张图片完美的将其挡住。

网易音乐版轮播-react组件版本
接下来,进行事件添加。我们先不管轮播下方的一排导航点。先加上左右点击操作。

在蒙板层加上onClick操作,(也可以加在slide层) 如下:
<div
    className={item.name === 'middle' ? '' : styles.masking}
    onClick={() => this.slide(item.name, key)}
>{''}</div>

点击图片时的方法

slide(name, key) {  // 图片点击逻辑
    // 记录当前节点
    this.setState({ current: key });
    // 数组操作方法
    this.imgArr(name);
  }

数组操作方法

imgArr(name) { // 数组处理
    let dirCopy = this.state.dir;
    if (name === 'start') {  // 点击左侧那张
      const pop = dirCopy.pop(); // 从数组尾部弹出一个元素
      dirCopy.unshift(pop); // 尾部元素添加到数组头部
    } else if (name === 'end') { // 点击右侧那张
      const shift = dirCopy.shift(); // 从数组头部弹出一个元素
      dirCopy.push(shift);  // 添加到数组尾部
    }
    this.setState({ dir: dirCopy }); // 保存重新排列的数组 并触发render
}

过渡样式添加

1.过渡样式主要有旋转时,蒙版层的渐变。
2.旋转时平滑的定位过渡。
3.旋转时层级的变化放在优化环节单独讲解。
.slide{
    ... , // 此处为原样式保留的意思(下面都以此规则显示)
    transition: all 0.3s ease-in-out;
    user-select: none; // 禁止用户选中(防止图片被选中时变色);
    &:hover{ // 鼠标经过时显示小手样式
      cursor: pointer;
    }
}
.masking{
    ... ,
    transition: all 0.3s 0.2s linear;
}
&.middle{
    ... ,
    .masking{
      background: transparent;
    }
}

这个样子的话点击图片左右两侧时就可以初步旋转起来了。

网易音乐版轮播-react组件版本

到此为止的步骤所完成的样式轮播为最基础的‘旋转木马es6版本’,有需要的朋友已经可以在以上代码中进行优化总结,放在自己的项目中去。

菜单按钮开发

动态的根据图片的数量循环出菜单按钮的数量,代码跟图片循环类似。

<div className={styles.slideBox}>
  ... ,
  {/* 导航按钮*/}
  <div className={styles.point}>
    {
      this.state.dir.map((item, key) => { // 根据图片数量进行循环
        return (
          <span
            key={key}
            className={item.name === 'start' ? styles.hover : ''} // 给予当前显示的按钮样式变化
            onMouseEnter={() => this.pointFunc(key - 1)} // 鼠标进入动画
          >{}</span>
        );
      })
    }
  </div>
</div>

样式方面:

  .point{
    width: 100%;
    position: absolute;
    left: 0;
    bottom: -23px;
    z-index: 999;
    text-align: center;
    span{
      display: inline-block;
      width: 20px;
      height: 3px;
      background-color: #2E3033;
      margin-left: 9px;
      &.hover{
        background-color: #7F8082;
      }
      &:hover{
        cursor: pointer;
      }
    }
  }

鼠标进入方法pointFunc();

  pointFunc(index) { // 按钮点击
    const { current } = this.state;
    const dirCopy = this.state.dir;
    if (index < current) { // 鼠标经过左侧的按钮
      for (let i = 0; i < (current - index); i += 1) { // 判断距离
        const shift = dirCopy.shift(); // 进行数组操作
        dirCopy.push(shift);
      }
    } else if (index > current) { // 鼠标经过右侧的按钮
      for (let i = 0; i < (index - current); i += 1) {
        const pop = dirCopy.pop();
        dirCopy.unshift(pop);
      }
    }
    this.setState({ dir: dirCopy }); // 触发react-render重新渲染页面
    this.setState({ current: index }); // 记录当前图片节点
  }

加完按钮图片后效果如下:

网易音乐版轮播-react组件版本
这个时候,核心效果已经出来了,经过严谨的布局和动画调节后,最终达到了预期的网易播放器的特殊动画效果。(鼠标经过相邻的图片时为滑动,经过不相邻图片按钮的时候改为跳动效果)。

代码效果

网易音乐版轮播-react组件版本
注:样式方面还有需要优化的地方请自行调节


总结

在这个组件模式开发时代,如果你做的东西不能保留下来并且开放出去,我认为是一件可悲的事情。所以下一篇文章将把此react组件进行开放式处理,开放一些可调节接口、响应式处理,并且最后打包成npm包,以插件的形式开放出去。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
CuterCorley CuterCorley
4年前
Django+Vue开发生鲜电商平台之11.首页、商品数量、缓存和限速功能开发
青,取之于蓝而青于蓝;冰,水为之而寒于水。——《荀子·劝学》Github和Gitee代码同步更新:;。一、首页功能完善首页待完善的功能包括轮播图、新品尝鲜、系列商品等。1.轮播图实现轮播图包括3张图片,链接对应3个商品,先在apps/goods/serializers.py中定义序列化如下:pythonclassBanner
Stella981 Stella981
3年前
Javascript使用三大家族和事件来DIY动画效果相关笔记(四)
1.图片轮播基础之缓速轮播◆使用封装的缓慢速动画来DIY滑动轮播图,也就是鼠标移动到123456这些数字上后,图片以缓慢速滑动的方式进行切换。<!DOCTYPEhtml<htmllang"en"<head<metacharset"UTF8"<title使用封装的缓速
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
DataGear 制作按行滚动的轮播表格数据可视化看板
通过DataGear(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fdatagear.tech%2F)的表格图表轮播设置项(1.13.0版本新增),可以轻松制作按行滚动的轮播表格数据可视化看板。首先,新建表格所需的数据集,以如下CSV数据集为例:name,v
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
程序员一鸣 程序员一鸣
3天前
HarmonyOs开发:轮播图Banner组件封装与使用
轮播图在每个项目中都很常见,鸿蒙中在容器组件中也提供了Swiper组件,用于子组件滑动轮播显示,和前端的使用起来也是异曲同工,我们先看下基本的用法。