话不多说,上视频: https://www.bilibili.com/video/BV1p44y1M7KC/
介绍
起因是我的一个小项目用到了网易云音乐的外链播放器;于是将它从项目里剥离出来做成一个Vue组件;并开源献给网友们。
它能使外链播放器很优雅的浮动在页面上,支持鼠标和触摸屏拖动、自动贴边;不占空间支持收缩/展开。 对细节方面做的很漂亮,配合Vue可以实现全站无刷新音乐播放功能。 需要的朋友拿走,有能力的小伙伴可以尝试将它与VuePress配合服用;一个更优雅的博客就诞生了。 具体长什么样子这里就来张图吧,其他的看视频
使用
依赖:它需要使用npm安装jquery和ElementUI;这两个可以单独引入这个组件文件(jquery我已经引入好了;只需要再引入ElementUI) 使用方面:上代码 这是demo,在App.vue引入时的代码,当然也可以在其他任何Vue页面引入该组件。
<template>
<div id="app">
<NeteaseCloudPlayForVue url="//music.163.com/outchain/player?type=2&id=1817694137&auto=1&height=66"/>
</div>
</template>
<script>
import NeteaseCloudPlayForVue from './components/NeteaseCloudPlayForvue.vue'
export default {
name: 'App',
inheritAttrs: false,
components: {
NeteaseCloudPlayForVue
},
}
</script>
组件代码:
<template>
<div>
<div
v-bind:class="NeteaseCloudPlayIframeClass"
v-bind:style="NeteaseCloudPlayIframeStyle"
@mousedown="NeteaseCloudPlayIframeMouseDownOrUp = true"
@mouseup="NeteaseCloudPlayIframeMouseDownOrUp = false"
@touchend="NeteaseCloudPlayIframeMouseDownOrUp = false"
@touchstart="NeteaseCloudPlayIframeMouseDownOrUp = true"
@touchmove.prevent.stop="NeteaseCloudPlayIframeForTouchClick($event)"
>
<el-row>
<el-col :span="NeteaseIconSpan">
<div
v-bind:class="NeteaseCloudPlayIframeClassIcon"
@mousedown="NeteaseShowClick"
@mouseup="NeteaseIconUp = true"
>
<el-row>
<el-col :pull="4" :span="1">
<i v-bind:class="NeteaseIconClass"></i>
</el-col>
</el-row>
</div>
</el-col>
<el-col :span="23">
<div
v-bind:class="NeteaseCloudPlayIframeDivClass"
v-bind:style="NeteaseCloudPlayIframeDivStyle"
>
<iframe
border="0"
frameborder="no"
height="86"
marginheight="0"
marginwidth="0"
v-bind:src="url"
v-bind:style="NeteaseCloudPlayIframeIframeStyle"
width="280"
></iframe>
</div>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import $ from "jquery";
export default {
name: 'NeteaseCloudPlayForVue',
props: {
url: String
},
data() {
return {
NeteaseCloudPlayIframeClass: "NeteaseCloudPlayIframe",
NeteaseCloudPlayIframeStyle: "left:60px;top:40%;",
NeteaseCloudPlayIframeMouseDownOrUp: false,
NeteaseCloudPlayIframeClassIcon: "NeteaseCloudPlayIframeIcon",
NeteaseCloudPlayIframeDivStyle: "left:-270px;",
NeteaseCloudPlayIframeWindowWidth: 0,
NeteaseIconSpan: 1,
NeteaseIconClass: "el-icon-arrow-left",
NeteaseCloudPlayIframeDivClass: "NeteaseCloudPlayIframeDiv",
NeteaseGPSLeftOrRight: true,
NeteaseGPSTop: 0,
NeteaseGPSLeft: 0,
NeteaseIfMove: false,
NeteaseIconUp: false,
NeteaseLockIframeIframeStyle: true,
NeteaseCloudPlayIframeIframeStyle:
"mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 100%, rgba(0, 0, 0, 1) 0%);",
};
},
methods: {
NeteaseCloudPlayIframeClick(event) {
var e = event || window.event;
var ValueX = e.pageX || e.clientX + document.body.scroolLeft;
var ValueY = e.pageY || e.clientY + document.body.scrollTop;
var x = ValueX - 10;
var y = ValueY - 45;
if (this.NeteaseCloudPlayIframeMouseDownOrUp == true) {
if (this.NeteaseCloudPlayIframeClass != "NeteaseCloudPlayIframe") {
this.NeteaseCloudPlayIframeClass = "NeteaseCloudPlayIframe";
}
var HalfWindowWidth = this.NeteaseCloudPlayIframeWindowWidth / 2;
var ToCenterLong = ValueX - HalfWindowWidth;
if (ToCenterLong > 0) {
this.NeteaseCloudPlayIframeStyle =
"left:" + x + "px;" + "top:" + y + "px;";
this.NeteaseGPSLeft = x;
this.NeteaseGPSTop = y;
if (ToCenterLong < 270) {
if (this.NeteaseGPSLeftOrRight != false) {
this.NeteaseIconFlipClick();
this.NeteaseGPSLeftOrRight = false;
if (this.NeteaseLockIframeIframeStyle == false) {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
} else {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv";
this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
}
}
}
} else {
this.NeteaseCloudPlayIframeStyle =
"left:" + x + "px;" + "top:" + y + "px;";
this.NeteaseGPSLeft = x;
this.NeteaseGPSTop = y;
if (HalfWindowWidth - ValueX < 270) {
if (this.NeteaseGPSLeftOrRight != true) {
this.NeteaseIconFlipClick();
this.NeteaseGPSLeftOrRight = true;
if (this.NeteaseLockIframeIframeStyle == false) {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
} else {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv";
this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
}
}
}
}
this.NeteaseIfMove = true;
}
},
NeteaseCloudPlayIframeForTouchClick(event) {
var ValueX = event.targetTouches[0].clientX;
var ValueY = event.targetTouches[0].clientY;
var x = ValueX - 10;
var y = ValueY - 45;
if (this.NeteaseCloudPlayIframeMouseDownOrUp == true) {
if (this.NeteaseCloudPlayIframeClass != "NeteaseCloudPlayIframe") {
this.NeteaseCloudPlayIframeClass = "NeteaseCloudPlayIframe";
}
var HalfWindowWidth = this.NeteaseCloudPlayIframeWindowWidth / 2;
var ToCenterLong = ValueX - HalfWindowWidth;
if (ToCenterLong > 0) {
this.NeteaseCloudPlayIframeStyle =
"left:" + x + "px;" + "top:" + y + "px;";
this.NeteaseGPSLeft = x;
this.NeteaseGPSTop = y;
if (ToCenterLong < 270) {
if (this.NeteaseGPSLeftOrRight != false) {
this.NeteaseIconFlipClick();
this.NeteaseGPSLeftOrRight = false;
if (this.NeteaseLockIframeIframeStyle == false) {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
} else {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv";
this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
}
}
}
} else {
this.NeteaseCloudPlayIframeStyle =
"left:" + x + "px;" + "top:" + y + "px;";
this.NeteaseGPSLeft = x;
this.NeteaseGPSTop = y;
if (HalfWindowWidth - ValueX < 270) {
if (this.NeteaseGPSLeftOrRight != true) {
this.NeteaseIconFlipClick();
this.NeteaseGPSLeftOrRight = true;
if (this.NeteaseLockIframeIframeStyle == false) {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
} else {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv";
this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
}
}
}
}
this.NeteaseIfMove = true;
}
},
NeteaseCloudPlayIframeWindowWidthClick() {
this.NeteaseCloudPlayIframeWindowWidth = $(window).width();
},
NeteaseIconFlipClick() {
if (this.NeteaseIconClass == "el-icon-arrow-left") {
this.NeteaseIconClass = "el-icon-arrow-right";
} else {
this.NeteaseIconClass = "el-icon-arrow-left";
}
},
NeteaseHelpToEdge() {
if (this.NeteaseCloudPlayIframeMouseDownOrUp == false) {
if (this.NeteaseIfMove == true) {
if (
this.NeteaseCloudPlayIframeClass !=
"NeteaseCloudPlayIframe NeteaseCloudPlayIframeTransition"
) {
this.NeteaseCloudPlayIframeClass =
"NeteaseCloudPlayIframe NeteaseCloudPlayIframeTransition";
}
if (this.NeteaseGPSLeftOrRight == true) {
this.NeteaseCloudPlayIframeStyle =
"left:" + 60 + "px;" + "top:" + this.NeteaseGPSTop + "px;";
} else {
this.NeteaseCloudPlayIframeStyle =
"left:" +
(this.NeteaseCloudPlayIframeWindowWidth - 80) +
"px;" +
"top:" +
this.NeteaseGPSTop +
"px;";
}
}
}
},
NeteaseShowClick() {
this.NeteaseIconUp = false;
setTimeout(() => {
if (this.NeteaseIconUp == true) {
this.NeteaseCloudPlayIframeDivClass =
"NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeDivTransition";
let i;
let x;
let Show;
let NotShow;
if (this.NeteaseGPSLeftOrRight == true) {
if (this.NeteaseCloudPlayIframeDivStyle != "left:-270px;") {
this.NeteaseIconFlipClick();
this.NeteaseLockIframeIframeStyle = true;
this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
i = 0;
NotShow = setInterval(() => {
i++;
x = i + 20;
if (i == 100) {
x = 100;
}
this.NeteaseCloudPlayIframeIframeStyle =
"mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) " +
i +
"%, rgba(0, 0, 0, 1) " +
x +
"%);";
if (i == 100) {
clearInterval(NotShow);
}
}, 10);
} else {
this.NeteaseIconFlipClick();
this.NeteaseLockIframeIframeStyle = false;
this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
i = 100;
Show = setInterval(() => {
i--;
x = i + 20;
if (i == 0) {
x = 0;
}
this.NeteaseCloudPlayIframeIframeStyle =
"mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) " +
i +
"%, rgba(0, 0, 0, 1) " +
x +
"%);";
if (i == 0) {
clearInterval(Show);
}
}, 10);
}
} else {
if (this.NeteaseCloudPlayIframeDivStyle != "left:0px;") {
this.NeteaseIconFlipClick();
this.NeteaseLockIframeIframeStyle = true;
this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
i = 0;
NotShow = setInterval(() => {
i++;
x = i + 20;
if (i == 100) {
x = 100;
}
this.NeteaseCloudPlayIframeIframeStyle =
"mask-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0) " +
i +
"%, rgba(0, 0, 0, 1) " +
x +
"%);";
if (i == 100) {
clearInterval(NotShow);
}
}, 10);
} else {
this.NeteaseIconFlipClick();
this.NeteaseLockIframeIframeStyle = false;
this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
i = 100;
Show = setInterval(() => {
i--;
x = i + 20;
if (i == 0) {
x = 0;
}
this.NeteaseCloudPlayIframeIframeStyle =
"mask-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0) " +
i +
"%, rgba(0, 0, 0, 1) " +
x +
"%);";
if (i == 0) {
clearInterval(Show);
}
}, 10);
}
}
}
}, 200);
},
},
mounted() {
$(() => {
$(window).mousemove(this.NeteaseCloudPlayIframeClick);
this.NeteaseCloudPlayIframeWindowWidthClick();
$(window).resize(this.NeteaseCloudPlayIframeWindowWidthClick);
$(window).mouseup(this.NeteaseHelpToEdge);
$(window).on("touchend", this.NeteaseHelpToEdge);
});
}
}
</script>
<style scoped>
.NeteaseCloudPlayIframe {
position: fixed;
width: 0;
}
.NeteaseCloudPlayIframeIcon {
user-select: none;
top: 10px;
position: absolute;
height: 66px;
width: 18px;
background-color: #dcdfe6;
z-index: 1;
}
.NeteaseCloudPlayIframeDiv {
position: relative;
}
.NeteaseCloudPlayIframeIcon i {
position: absolute;
top: 22px;
font-size: 25px;
color: #606266;
}
.NeteaseCloudPlayIframeTransition {
transition: all 1s ease;
}
.NeteaseCloudPlayIframeDivTransition {
transition: all 1s linear;
}
</style>
代码没加多少注释哈,我认为命名已经很明确了。 感谢🙏你看到我的文章,希望能帮到你。
|