vue做的一个一点就转的转盘(音乐磁盘),点击停止时会在几秒内缓慢停止,再次点击按钮可以再次旋转,

先看效果:

代码:主要部分我会红线画出来

css:部分:

源码:

vue部分:

<template>

	<div class="song-lyric">

		<div>
			<div class="type">
				<div class="right">
					<div class="right-center" :class="{ 'rotates': isplay }">
						<div>
							<img src="https://imagesone.oss-cn-beijing.aliyuncs.com/imagebishe/player_bar.png"
								class="right-top" :class="{rotated: isplay}">
						</div>
						<div>
							<img src="https://imagesone.oss-cn-beijing.aliyuncs.com/imagebishe/disc.png"
								class="tight-bottm" :style="{ transform: 'rotate(' + rotationAngle + 'deg)' }">
						</div>
					</div>
				</div>
				<div class="lyric-title">
					<!-- 有歌词 -->
					<!-- <el-input v-model="input" placeholder="请输入内"></el-input>
			<el-input v-model="input" placeholder="差不多"></el-input> -->
					<ul class="has-lyric" v-if="lyr.length" key="index">
						<li v-for="(item,index) in lyr" v-bind:key="index">
							{{item[1]}}
						</li>
					</ul>
					<!-- 没有歌词 -->
					<div v-else class="no-lyric" key="no-lyric">
						<span>暂无歌词</span>
					</div>
				</div>
			</div>

		</div>


	</div>


</template>
<script>
	import {
		mixin
	} from '../mixins';
	import {
		mapGetters
	} from 'vuex';

	export default {
		name: 'lyric',
		mixins: [mixin],
		data() {
			return {
				// input: '',
				lyr: [], //当前歌曲的歌词
				isplay: undefined, //获取歌曲开关状态
				rotationAngle: 0 // 记录盒子当前的旋转角度
			}
		},
		computed: {
			
			...mapGetters([
				'curTime', //当前歌曲播放到的位置
				'id', //当前播放的歌曲id
				'lyric', //歌词
				'listIndex', //当前歌曲在歌单中的位置
				'listOfSongs', //当前歌单列表
				'isPlay' //播放状态
			])
		},
		created() {
			this.isplay = this.isPlay//获取开关
			console.log('data', this.isplay);//获取点击图片进去歌词页面的开关状态
			this.lyr = this.lyric;
			this.rotateBox();

			console.log('this.lyr', this.lyr)
			console.log('this.mapGetters', this.mapGetters)
		},
		watch: {
			isPlay() {
				this.isplay = this.isPlay
				console.log('data', this.isplay);
				this.rotateBox();
			},
			id: function() {
				this.lyr = this.parseLyric(this.listOfSongs[this.listIndex].lyric)
			},
			curTime: function() {
				if (this.lyr.length > 0) {
					for (let i = 0; i < this.lyr.length; i++) {
						if (this.curTime >= this.lyr[i][0]) {
							for (let j = 0; j < this.lyr.length; j++) {
								document.querySelectorAll('.has-lyric li')[j].style.color = '#ffffff';
								document.querySelectorAll('.has-lyric li')[j].style.fontSize = '15px';
							}
							if (i >= 0) {
								document.querySelectorAll('.has-lyric li')[i].style.color = '#95d2f6';
								document.querySelectorAll('.has-lyric li')[i].style.fontSize = '25px';
							}
						}
					}
				}
			}
		},
		methods:{
		  
			rotateBox(){
				if(this.isplay){
					this.rotationAngle +=1;
					// if(this.rotationAngle >= 360){
					// 	this.rotationAngle = this.rotationAngle % 360;
					// }
					setTimeout(this.rotateBox, 20);
					// console.log('this.rotateBox',this.rotationAngle)
				}
			}
			   
		}
	}
</script>
<style lang="scss" scoped>
	@import '../assets/css/lyric.scss';
</style>

css部分:

@import "var.scss";


.song-lyric {
  // margin: auto;
  // margin-top: $header-height + 20px;
  width: 100%;
  height: 100%;
  // background-color: $color-white;
  border-radius: 12px;
  display: block;
  background-color: rgb(167, 167, 167);
  // padding: 0 20px 50px 20px;
  // background-color: rgba(0,0,0,.55);
  font-family: $font-family;

  // background-size: cover;
  // filter: blur(30px);
  z-index: 1;

  .lyric-title {
    text-align: center;
	  width: 50%;
    height: 100vh;
		overflow-y: scroll;
    line-height: 60px;
    border-bottom: 2px solid $color-black;
	margin-top: 50px;
	// background: rgba(21, 21, 21, 0.6);
	background-color: rgba(0,0,0,.65);

	z-index: 2;
  }

  .type{
	  display: flex;
	  text-align: center;
	    width: 100%;
	  height: 100vh;
	  	overflow: hidden;
	  line-height: 60px;
	  border-bottom: 2px solid $color-black;
	  z-index: 2;
  }
  .right{
	  text-align: center;
	    width: 50%;
	  height: 100vh;
	  	overflow: hidden;
	  line-height: 60px;
	  border-bottom: 2px solid $color-black;
	  margin-top: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    flex-wrap: wrap;
	  // background: rgba(21, 21, 21, 0.6);
	  background-color: rgba(0,0,0,.65);
	  // backdrop-filter: blur(4px);
	  // box-shadow: inset 0px 1px 6px rgba(255,255,255,0.6), 2px 2px 15px rgba(0,0,0,0.5);
	  z-index: 2;
  }
  
  .right-top{ //指针
    position: absolute; 
	z-index: 1; 
	width: auto; 
	left:45%; 
	top:117px; 
	height:200px;
	
	transition: transform 0.7s linear;  transform: rotate(-30deg) translate(35px , -10px); 
  }
   
  .rotated {
    transform: rotate(0deg);
  }
  
  

  .right-center{
    position: relative;
    width: 600px;
    height: 1000px;
    // background-color: rgb(206, 198, 198);
  }

  .has-lyric {
    font-size: 18px;
    width: 100%;
    min-height: 100%;
    text-align: center;
	padding-top: 120px;
    li {
      width: 100%;
      height: 40px;
      line-height: 40px;
    }
  }

  .no-lyric {
    // margin: 200px 0;
	padding: 200px 0 0 0;
    width: 100%;
    text-align: center;

    span {
      font-size: 18px;
      text-align: center;
    }
  }
}

.lyric-fade-enter,
.lyric-fade-leave-to {
  transform: translateX(30px);
  opacity: 0;
}

.lyric-fade-enter-active,
.lyric-fade-leave-active {
  transition: all 0.3s ease;
}

.tight-bottm{ //圆
    position: absolute;
    top:225px;  
    width: 400px; 
    left:18%; 
    height:400px; 
    border-radius: 50%;
	transition: transform 0.7s linear;
	
  }
  
  .active {
	  animation: none !important;
    // animation: spin 5s linear infinite;
  }
  
  // @keyframes spin {
  //   100% {
  //     transform: rotate(360deg);
  //   }
  // }
相关推荐
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui
尝尝你的优乐美6 小时前
vue3.0中h函数的简单使用
前端·javascript·vue.js
windy1a6 小时前
【C语言】js写一个冒泡顺序
javascript