当前位置: 首页 > news >正文

angularjs网站模板/东莞免费建站公司

angularjs网站模板,东莞免费建站公司,中国十大营销策划大师,wordpress怎么搭建网站今天我们做歌曲的单曲循环,按序播放,随机播放以及通过手动点击上一首,下一首这些功能哈,下一篇博客就写我们歌词滚动功能 由于我每篇都和前面是联系在一起的,如果想获取整个项目,可以去我的github下载源码…

今天我们做歌曲的单曲循环,按序播放,随机播放以及通过手动点击上一首,下一首这些功能哈,下一篇博客就写我们歌词滚动功能
在这里插入图片描述

由于我每篇都和前面是联系在一起的,如果想获取整个项目,可以去我的github下载源码

首先到我们的组件中,分三步来写(之前的逻辑我没删除)

第一步,导入的配置

import React, { memo, useState, useEffect, useRef, useCallback } from 'react';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';import { getSizeImage, formatDate, getPlaySong } from '@/utils/format-utils';import { NavLink } from 'react-router-dom';
import { Slider,message } from 'antd';import { getSongDetailAction,changeSequenceAction,changeCurrentIndexAndSongAction,changeCurrentLyricIndexAction } from '../store/actionCreators';
import {PlaybarWrapper,Control,PlayInfo,Operator
} from './style';

这些就没必要说了

第二步,我们的逻辑代码

 // props and stateconst [currentTime, setCurrentTime] = useState(0);const [progress, setProgress] = useState(0);const [isChanging, setIsChanging] = useState(false);const [isPlaying, setIsPlaying] = useState(false);const [showPanel, setShowPanel] = useState(false);// redux hookconst { currentSong,sequence,playList,lyricList,currentLyricIndex } = useSelector(state => ({playList:state.getIn(["player","playList"]),currentSong: state.getIn(["player", "currentSong"]),sequence: state.getIn(["player", "sequence"]),lyricList: state.getIn(["player", "lyricList"]),currentLyricIndex: state.getIn(["player", "currentLyricIndex"])}), shallowEqual);const dispatch = useDispatch();// other hooksconst audioRef = useRef();useEffect(() => {dispatch(getSongDetailAction(167876));}, [dispatch]);useEffect(() =>  {audioRef.current.src = getPlaySong(currentSong.id);audioRef.current.play().then(res => {setIsPlaying(true);}).catch(err => {setIsPlaying(false);});}, [currentSong]);// other handleconst picUrl = (currentSong.al && currentSong.al.picUrl) || "";const singerName = (currentSong.ar && currentSong.ar[0].name) || "未知歌手";const duration = currentSong.dt || 0;const showDuration = formatDate(duration, "mm:ss");const showCurrentTime = formatDate(currentTime, "mm:ss");// handle functionconst playMusic = useCallback(() => {isPlaying ? audioRef.current.pause(): audioRef.current.play();setIsPlaying(!isPlaying);},[isPlaying])const timeUpdate = (e) => {const currentTime = e.target.currentTime;if (!isChanging) {setCurrentTime(e.target.currentTime * 1000);setProgress(currentTime * 1000 / duration * 100);}}//变换0,1,2,循环,单曲等const changeSequence = () => {let currentSequence = sequence + 1;if (currentSequence > 2) {currentSequence = 0;}dispatch(changeSequenceAction(currentSequence));}//上一首,下一首const changeMusic = (tag) => {dispatch(changeCurrentIndexAndSongAction(tag));}//歌曲播放完之后const handleMusicEnded = () => {if (sequence === 2) { // 单曲循环audioRef.current.currentTime = 0;audioRef.current.play();} else {dispatch(changeCurrentIndexAndSongAction(1));}}//useCallback:当把一个回调函数传到一个自定义组件内部时候用const sliderChange = useCallback((value) => {setIsChanging(true);const currentTime = value / 100 * duration;setCurrentTime(currentTime);setProgress(value);}, [duration]);const sliderAfterChange = useCallback((value) => {const currentTime = value / 100 * duration / 1000;audioRef.current.currentTime = currentTime;setCurrentTime(currentTime * 1000);setIsChanging(false);if (!isPlaying) {playMusic();}}, [duration,isPlaying, playMusic]);

我就说一下,跟我们这个demo有关的一些

 //变换0,1,2,循环,单曲等const changeSequence = () => {let currentSequence = sequence + 1;if (currentSequence > 2) {currentSequence = 0;}dispatch(changeSequenceAction(currentSequence));}//上一首,下一首const changeMusic = (tag) => {dispatch(changeCurrentIndexAndSongAction(tag));}//歌曲播放完之后const handleMusicEnded = () => {if (sequence === 2) { // 单曲循环audioRef.current.currentTime = 0;audioRef.current.play();} else {dispatch(changeCurrentIndexAndSongAction(1));}}

我们在redux里面定义了一个变量sequence

sequence: 0, // 0 循环 1 随机 2 单曲

解析:

changeSequence点击事件:我们初始化是0,也就是最开始的时候是根据列表顺序循环,点击一次就+1,也就是成随机循环了,依次类推三个循环,再通过dispatch改变我们redux里面的sequence

store里面

reducer.js

import { Map } from 'immutable';import * as actionTypes from './constants';const defaultState = Map({sequence: 0, // 0 循环 1 随机 2 单曲
});function reducer(state = defaultState, action) {switch(action.type) {case actionTypes.CHANGE_SEQUENCE:return state.set("sequence", action.sequence);default:return state;}
}export default reducer;

constants.js

export const CHANGE_SEQUENCE = "player/CHANGE_SEQUENCE";

actionCreators.js

export const changeSequenceAction = (sequence) => ({type: actionTypes.CHANGE_SEQUENCE,sequence
});

然后回到我的们组件

  //上一首,下一首const changeMusic = (tag) => {dispatch(changeCurrentIndexAndSongAction(tag));}

解析

这两个button,第一个点击就是上一首,第二个下一首

<button className="sprite_player prev" onClick={e => changeMusic(-1)}></button><button className="sprite_player next" onClick={e => changeMusic(1)}></button>通过点击事件再发送一个dispatch,changeCurrentIndexAndSongAction把tag传过去

到我们的actionCreators.js

export const changeCurrentIndexAndSongAction = (tag) =>{return (dispatch, getState) => {const playList = getState().getIn(["player", "playList"]);const sequence = getState().getIn(["player", "sequence"]);let currentSongIndex = getState().getIn(["player", "currentSongIndex"]);switch (sequence) {case 1:let randomIndex = getRandomNumber(playList.length);while (randomIndex === currentSongIndex) {randomIndex = getRandomNumber(playList.length);}currentSongIndex = randomIndex;break;default: currentSongIndex += tag;if (currentSongIndex >= playList.length) currentSongIndex = 0;if (currentSongIndex < 0) currentSongIndex = playList.length - 1;}const currentSong = playList[currentSongIndex];dispatch(changeCurrentSongAction(currentSong));dispatch(changeCurrentSongIndexAction(currentSongIndex));}
}

解析1

先获取到我们的playList,这个是我们的歌曲数组,sequence哪个状态,currentSongIndex是歌曲的下标,也是在redux中定义的

解析2

先通过判断sequence是多少,随机播放,这个地方需要一个随机数

getRandomNumber

export function getRandomNumber(num) {return Math.floor(Math.random() * num);
}

然后是这个

  //歌曲播放完之后const handleMusicEnded = () => {if (sequence === 2) { // 单曲循环audioRef.current.currentTime = 0;audioRef.current.play();} else {dispatch(changeCurrentIndexAndSongAction(1));}}

解析:

当我们不点击,等歌曲播放完之后,这个要根据我们选定点哪种状态,是循环,随机还是啥的来进行下一步

<audio  onEnded={e => handleMusicEnded()}/>

总的来说,跟前面几篇博客关系都太紧密了,可能分开后,有些没有写好,如果有不懂的可以去我github下载源码来进行学习

github项目地址:https://github.com/lsh555/WYY-Music

http://www.lbrq.cn/news/1342855.html

相关文章:

  • 网站设计就业怎么样/百度推广和优化哪个好
  • 网站可以在手机上做吗/免费模板
  • vue做网站对seo/2024年新冠疫情最新消息
  • 宁波最靠谱的网站建设/北京网站seo招聘
  • 企业vi手册范本/沈阳百度seo
  • 免费视频模板在线制作/西安百度快照优化
  • 推荐做木工的视频网站/南宁哪里有seo推广厂家
  • 建设部人事考试网站官网/免费推广网站
  • 沈阳有资质做网站的公司/爱站网关键词工具
  • 甘肃建设厅职称查询官方网站/网络营销策划方案的目的
  • 做名片去哪个网站/互联网广告行业分析
  • 公司注册网站方法/独立站搭建要多少钱
  • 哈尔滨建设网站成本/营销手段
  • 怎么网站做二维码/黑科技引流工具
  • 专业的网站建设/sem优化技巧
  • 做兼职什么网站好/专业seo站长工具
  • 俄罗斯网站模版/国内新闻今日头条
  • 大型服装网站建设/中国互联网域名注册服务机构
  • 广告设计网站排行榜前十名有哪些/网站营销网站营销推广
  • 重庆建设部网站/seo综合查询是什么
  • 网站建设教程自学/海口seo计费
  • 做推送的网站除了秀米还有/鼓楼网站seo搜索引擎优化
  • 微博账号滚动图网站怎么做/seo优化公司信
  • 网站原型图大小/最新消息今天的新闻
  • 前端做项目网站/如何获取网站的seo
  • 衢州网站建设有限公司/整站优化seo
  • 电子商务网站建设可用性/网页设计制作网站代码
  • 网站开发要学多久/济南疫情最新消息
  • 甘肃省建设银行网站/永久免费开网店app
  • 南昌电商网站设计/优化营商环境的意义
  • vuhub drippingblues靶场攻略
  • Redis如何实现一个分布式锁?
  • 动态规划(三维)直接按照题目条件
  • 深入理解 Gin 框架的路由机制:从基础使用到核心原理
  • NTP /Chrony 网络时间协议
  • day16 - CSS3新增属性