此版本輪播圖爲仿照網易雲音樂PC播放器上首頁的輪播。react
網易的輪播特殊的地方就在於,若是你滑動不相鄰的兩張圖片,其過渡效果並非滑動過渡,而是一個跳出過渡,此方面原理與最開始設計輪播排版時候有極大關聯。git
此輪播爲純react環境下的es6寫法,經過對state中數組的重組排列,配合樣式。達到輪播的效果es6
無任何依賴,最終效果爲封裝成react組件開放接口併發布出去github
注:此文章爲正推,並在開發完成後進行總結優化。npm
此方面的文章應該不少,我就沒必要過多介紹,去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以下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; } } } }
這樣最開始的位置就擺好了。
隱藏圖片的位置很重要,由於上面也說了,跨圖片滑動時須要改爲跳出效果。大概在以下位置,展現的那張圖片完美的將其擋住。
接下來,進行事件添加。咱們先無論輪播下方的一排導航點。先加上左右點擊操做。
在蒙板層加上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; } }
這個樣子的話點擊圖片左右兩側時就能夠初步旋轉起來了。
到此爲止的步驟所完成的樣式輪播爲最基礎的‘旋轉木馬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組件進行開放式處理,開放一些可調節接口、響應式處理,而且最後打包成npm包,以插件的形式開放出去。