Browse Source

优化视频播放页,但是双击爱心效果好卡

pull/19/head
zyronon 4 years ago
parent
commit
b379a9438d
  1. 1
      src/App.vue
  2. 115
      src/components/BaseMarquee.vue
  3. 163
      src/components/BaseMusic.vue
  4. 5
      src/components/Footer.vue
  5. 417
      src/components/Video.vue
  6. 193
      src/components/common/Music.vue
  7. 1
      src/components/slide/SlideColumnVirtualList.vue
  8. 3
      src/pages/Test3.vue
  9. 71
      src/pages/Test4.vue
  10. 66
      src/pages/Test5.vue
  11. 107
      src/pages/home/Index2.vue
  12. 199
      src/pages/home/Music.vue
  13. 4
      src/router/index.js
  14. 72
      src/utils/dom.js

1
src/App.vue

@ -53,6 +53,7 @@ export default {
'/message', '/attention', '/home', '/me', '/publish', '/message', '/attention', '/home', '/me', '/publish',
'/home/report', '/home/report',
'/home/submit-report', '/home/submit-report',
'/home/music',
'/message/share-to-friend', '/message/share-to-friend',
'/message/joined-group-chat', '/message/joined-group-chat',
'/country-choose', '/country-choose',

115
src/components/BaseMarquee.vue

@ -0,0 +1,115 @@
<template>
<div class="marquee" :class="name+'-marquee'" ref="marquee">
<span class="text" ref="marqueeText">
{{ text }}<span class="space"></span>
{{ text }}<span class="space"></span>
{{ text }}<span class="space"></span>
</span>
</div>
</template>
<script>
import Dom from "../utils/dom";
import {nextTick} from "vue";
export default {
name: "BaseMarquee",
props: {
text: {
type: String,
default: ''
},
name: {
type: String,
default: ''
},
//
isPlay: {
type: Boolean,
default: () => {
return true
}
},
},
data() {
return {
timer: null,
contentWidth: 0,
transformX: 0,
$marqueeContent: null,
}
},
methods: {
pause() {
// console.log('pause')
cancelAnimationFrame(this.timer)
},
stop() {
// console.log('stop')
cancelAnimationFrame(this.timer)
this.transformX = 0
this.marqueeText.css('transform', `translate3d(0,0,0)`)
},
start() {
// console.log('start')
if (this.contentWidth <= 0) { //
return;
}
let fn = () => {
if (this.transformX > (-this.contentWidth / 3)) {
this.transformX -= 1
this.marqueeText.css('transform', `translate3d(${this.transformX}px,0,0)`)
} else {
this.transformX = 0
}
this.timer = requestAnimationFrame(fn)
}
fn()
}
},
mounted() {
nextTick(() => {
//document.querySelectorAlldom$refs
this.marqueeText = new Dom(this.$refs.marqueeText)
//nextTickdomwidth
this.contentWidth = this.marqueeText.getWidth()
// console.log(this.name, this.isPlay, this.marqueeText)
// console.log(this.name, this.isPlay, this.contentWidth)
new Dom(this.$refs.marquee).on('pause', this.pause)
new Dom(this.$refs.marquee).on('start', this.start)
new Dom(this.$refs.marquee).on('stop', this.stop)
if (this.isPlay) {
this.start()
}
})
}
}
</script>
<style scoped lang="less">
.marquee {
width: 100%;
display: block;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
text-overflow: clip;
position: relative;
.text {
color: white;
display: inline-block;
position: relative;
white-space: nowrap;
.space {
display: inline-block;
width: 5rem;
}
}
}
</style>

163
src/components/BaseMusic.vue

@ -0,0 +1,163 @@
<template>
<div class="music-wrapper" :class="name+'-music'" ref="musicWrapper">
<template v-if="!isStop">
<img class="music1" src="../assets/img/icon/home/music1.png" alt="">
<img class="music2" src="../assets/img/icon/home/music2.png" alt="">
</template>
<div class="music-bg" ref="musicBg">
<img class="music" :src="cover">
</div>
</div>
</template>
<script>
import Dom from "../utils/dom";
import {nextTick} from "vue";
import BaseButton from "./BaseButton";
export default {
name: "BaseMusic",
components: {
BaseButton
},
props: {
cover: {
type: String,
default: ''
},
name: {
type: String,
default: ''
},
//
isPlay: {
type: Boolean,
default: () => {
return true
}
},
},
data() {
return {
isStop: false,
musicBg: null,
}
},
methods: {
// triggerPause() {
// new Dom('.music-wrapper').trigger('pause')
// },
// triggerStart() {
// new Dom('.music-wrapper').trigger('start')
// },
pause() {
this.isStop = true
this.musicBg.css('webkitAnimationPlayState', 'paused')
},
stop() {
this.isStop = true
this.musicBg.css('webkitAnimationPlayState', 'paused')
},
start() {
this.isStop = false
this.musicBg.css('webkitAnimationPlayState', 'running')
}
},
mounted() {
nextTick(() => {
//document.querySelectorAlldom$refs
this.musicBg = new Dom(this.$refs.musicBg)
new Dom(this.$refs.musicWrapper).on('pause', this.pause)
new Dom(this.$refs.musicWrapper).on('start', this.start)
new Dom(this.$refs.musicWrapper).on('stop', this.stop)
if (this.isPlay) {
this.start()
} else {
this.stop()
}
})
}
}
</script>
<style lang="less">
.music-wrapper {
position: relative;
.music-bg {
background-image: linear-gradient(black, #424242, black);
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
animation: animations 5s linear forwards infinite;
//animation-play-state:paused;
//display: none;
.music {
//display: none;
width: 25px;
height: 25px;
border-radius: 50%;
}
}
.music1, .music2 {
//display: none;
position: absolute;
width: 18px;
height: 18px;
top: 10px;
}
.music1 {
animation: anim-music1 2s linear forwards infinite;
}
.music2 {
animation: anim-music1 2s linear forwards infinite;
animation-delay: 1s;
}
@keyframes animations {
0% {
transform: rotate(0deg);;
}
100% {
transform: rotate(360deg);
}
}
@keyframes anim-music1 {
0% {
transform: translate3d(0, 0, 0);
opacity: 0;
}
20% {
transform: translate3d(-8px, 0px, 0) rotate(30deg);
opacity: .3;
}
40% {
transform: translate3d(-16px, -5px, 0) rotate(15deg);
opacity: .5;
}
60% {
transform: translate3d(-24px, -15px, 0) rotate(0deg);
opacity: 1;
}
80% {
transform: translate3d(-32px, -30px, 0) rotate(-15deg);
opacity: 1;
}
100% {
transform: translate3d(-32px, -50px, 0) rotate(-30deg);
opacity: 0;
}
}
}
</style>

5
src/components/Footer.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="footer f16 " @touchmove.stop="false"> <div class="footer f16 ">
<div class="l-button" @click="refresh(1)"> <div class="l-button" @click="refresh(1)">
<span v-if="!isRefresh1" :class="{active:currentTab===1}">首页</span> <span v-if="!isRefresh1" :class="{active:currentTab===1}">首页</span>
<img v-if="isRefresh1 " src="../assets/img/icon/refresh1.png" alt="" class="refresh"> <img v-if="isRefresh1 " src="../assets/img/icon/refresh1.png" alt="" class="refresh">
@ -32,6 +32,9 @@ export default {
} }
}, },
methods: { methods: {
stop() {
},
tab(index) { tab(index) {
this.currentTab = index this.currentTab = index
switch (index) { switch (index) {

417
src/components/Video.vue

@ -1,21 +1,17 @@
<template> <template>
<div class="bg-video"> <div class="video-wrapper" ref="videoWrapper" :class="name">
<!-- <video :src="video.videoUrl" poster="../assets/img/icon/components/video/loading.gif" ref="video" muted :autoplay="play" loop>-->
<!-- poster="../assets/img/poster/1.jpg"-->
<video :src="video.video" <video :src="video.video"
:poster="video.origin_cover" :poster="video.origin_cover"
ref="video" ref="video"
muted muted
preload preload
:autoplay="play" loop> :autoplay="isPlay" loop>
<p> 您的浏览器不支持 video 标签</p> <p> 您的浏览器不支持 video 标签</p>
</video> </video>
<div class="float-container" v-if="true" @click.stop="togglePlayVideo"> <img src="../assets/img/icon/play.svg" class="pause" v-if="!isPlaying">
<transition name="pause"> <div class="float" @click.stop="checkDbClick">
<img src="../assets/img/icon/play.svg" class="pause" v-show="!isPlaying"> <!-- @click.stop="togglePlayVideo" -->
</transition> <div :style="{opacity:isMove ? 0:1}" class="normal">
<div class="float">
<div :style="{opacity:isMove?0:1}" class="normal">
<div class="toolbar mb1r"> <div class="toolbar mb1r">
<div class="avatar-ctn mb2r"> <div class="avatar-ctn mb2r">
<img class="avatar" :src="lVideo.author.avatar" alt="" <img class="avatar" :src="lVideo.author.avatar" alt=""
@ -51,14 +47,13 @@
<div v-else class="share mb4r" @click.stop="$emit('showShare')"> <div v-else class="share mb4r" @click.stop="$emit('showShare')">
<img src="../assets/img/icon/share.svg" alt="" class="share-image"> <img src="../assets/img/icon/share.svg" alt="" class="share-image">
</div> </div>
<div class="music-ctn"> <BaseMusic
<img class="music1" src="../assets/img/icon/home/music1.png" alt=""> :cover="lVideo.music.cover"
<img class="music2" src="../assets/img/icon/home/music2.png" alt=""> :key="name"
<div class="music-bg"> :name="name"
<img class="music" :src="lVideo.music.cover" alt="" :isPlay="isPlay"
@click.stop="globalMethods.$nav('/music')"> @click.stop="$emit('goMusic')"
</div> />
</div>
</div> </div>
<div class="content ml1r mb1r" v-if="!isMy"> <div class="content ml1r mb1r" v-if="!isMy">
<div class="name mb1r">{{ lVideo.author.name }}</div> <div class="name mb1r">{{ lVideo.author.name }}</div>
@ -67,13 +62,7 @@
</div> </div>
<div class="music" @click.stop="$nav('/music')"> <div class="music" @click.stop="$nav('/music')">
<img src="../assets/img/icon/music.svg" alt="" class="music-image"> <img src="../assets/img/icon/music.svg" alt="" class="music-image">
<!-- <marquee behavior=scroll direction=left align=middle scrollamount=4>{{ lVideo.music.title }}</marquee>--> <BaseMarquee :key="name" :name="name" :isPlay="isPlay" :text="lVideo.music.title"/>
<!-- <div class="marquee" behavior=scroll direction=left align=middle scrollamount=4>-->
<!-- {{ lVideo.music.title }}-->
<!-- </div>-->
<div class="marquee">
<p> {{ lVideo.music.title }}{{ lVideo.music.title }}</p>
</div>
</div> </div>
</div> </div>
<div v-else class="comment-status"> <div v-else class="comment-status">
@ -99,7 +88,7 @@
</div> </div>
<div class="process" <div class="process"
v-if="duration > 60" v-if="duration > 60"
:class="isMove ? '' : isPlaying && 'stop'" :class="processClass"
@touchmove="move" @touchmove="move"
@touchend="end" @touchend="end"
> >
@ -112,14 +101,20 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
import globalMethods from '../utils/global-methods' import globalMethods from '../utils/global-methods'
import BaseMarquee from "./BaseMarquee";
import Dom from "../utils/dom";
import BaseMusic from "./BaseMusic";
export default { export default {
name: "Video", name: "Video",
components: {
BaseMarquee,
BaseMusic
},
props: { props: {
video: { video: {
type: Object, type: Object,
@ -133,7 +128,8 @@ export default {
return -1 return -1
} }
}, },
play: { //
isPlay: {
type: Boolean, type: Boolean,
default: () => { default: () => {
return true return true
@ -149,25 +145,36 @@ export default {
computed: { computed: {
durationStyle() { durationStyle() {
return {left: this.pageX + 'px'} return {left: this.pageX + 'px'}
},
processClass() {
if (this.isMove) {
return 'stop'
} else {
return this.isPlaying ? '' : 'stop'
}
} }
}, },
data() { data() {
return { return {
name: `v-${this.index}-video`,
globalMethods: globalMethods, globalMethods: globalMethods,
duration: 0, duration: 0,
step: 0, step: 0,
currentTime: 0, currentTime: -1,
pageX: 0, pageX: 0,
height: 0, height: 0,
width: 0, width: 0,
isPlaying: !this.play, isPlaying: this.isPlay,
isAttention: false, isAttention: false,
line: null, line: null,
point: null, point: null,
isMove: false, isMove: false,
currentVideoId: 'a' + Date.now(),
test: [1, 2], test: [1, 2],
lVideo: this.video lVideo: this.video,
lastClickTime: -1,
clickTimer: null,
dbClickTimer: null,
isDbClick: false
} }
}, },
mounted() { mounted() {
@ -184,18 +191,99 @@ export default {
video.addEventListener('loadedmetadata', e => { video.addEventListener('loadedmetadata', e => {
this.duration = video.duration this.duration = video.duration
if (this.duration > 60) { if (this.duration > 60) {
// if (this.duration > 6) {
this.step = this.width / Math.floor(this.duration) this.step = this.width / Math.floor(this.duration)
video.addEventListener('timeupdate', fun) video.addEventListener('timeupdate', fun)
} }
}) })
video.addEventListener('play', e => {
this.isPlaying = true let videoWrapper = new Dom(this.$refs.videoWrapper)
videoWrapper.on('play', this.play)
videoWrapper.on('stop', this.stop)
},
methods: {
dbClick(e) {
console.log('dbclick')
setTimeout(() => {
let id = 'a' + Date.now()
let elWidth = 80
let rotate = this.randomNum(0, 1)
// let rotate = 1
let template = `<img class="${rotate ? 'left love-dbclick' : 'right love-dbclick'}" id="${id}" src="${require('../assets/img/icon/loved.svg')}" alt="">`
let el = new Dom().create(template)
el.css({top: e.y - elWidth, left: e.x - elWidth / 2,})
// new Dom().find('#home-index').append(el)
document.querySelector('#home-index').appendChild(el.els[0])
//
setTimeout(() => {
new Dom().find(`#${id}`).remove()
}, 1000)
}) })
video.addEventListener('pause', e => { },
randomNum(minNum, maxNum) {
switch (arguments.length) {
case 1:
return parseInt(Math.random() * minNum + 1, 10);
case 2:
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
default:
return 0;
}
},
checkDbClick(e) {
let checkTime = 400
if (this.isDbClick) {
this.dbClick(e)
console.log('checkDbClick-dbclick1')
clearTimeout(this.dbClickTimer);
this.dbClickTimer = setTimeout(() => {
this.isDbClick = false
}, 400);
}
let nowTime = new Date().getTime();
if (nowTime - this.lastClickTime < checkTime) {
this.dbClick(e)
console.log('checkDbClick-dbclick2')
this.lastClickTime = 0;
this.clickTimer && clearTimeout(this.clickTimer);
this.isDbClick = true
this.dbClickTimer = setTimeout(() => {
this.isDbClick = false
}, checkTime);
} else {
this.lastClickTime = nowTime;
this.clickTimer = setTimeout(() => {
console.log('单击')
this.togglePlayVideo()
}, checkTime);
}
},
play() {
new Dom(`.${this.name}-marquee`).trigger('start')
new Dom(`.${this.name}-music`).trigger('start')
// console.log('trigger-play')
this.isPlaying = true
if (this.currentTime !== -1) {
this.$refs.video.currentTime = this.currentTime
}
this.$refs.video.play()
},
stop() {
new Dom(`.${this.name}-marquee`).trigger('stop')
new Dom(`.${this.name}-music`).trigger('stop')
// console.log('trigger-stop')
this.$refs.video.pause()
this.isPlaying = false
this.$refs.video.currentTime = 0
},
pause() {
new Dom(`.${this.name}-marquee`).trigger('pause')
new Dom(`.${this.name}-music`).trigger('pause')
// console.log('trigger-pause')
this.$refs.video.pause()
this.isPlaying = false this.isPlaying = false
})
}, },
methods: {
$likeNum(v) { $likeNum(v) {
return globalMethods.$likeNum(v) return globalMethods.$likeNum(v)
}, },
@ -229,47 +317,15 @@ export default {
this.isAttention = true this.isAttention = true
}, 1000) }, 1000)
}, },
//
swipingVideo() {
let videos = this.$refs.video
if (this.currentIndex) {
videos[this.currentIndex - 1].pause()
}
videos[this.currentIndex].play()
videos[this.currentIndex].muted = false
videos[this.currentIndex + 1].pause()
this.isCommenting = false
this.isSharing = false
this.isPlaying = true
},
// //
togglePlayVideo(e) { togglePlayVideo(e) {
if (this.isSharing) { // console.log('togglePlayVideo')
this.isSharing = false if (this.isPlaying) {
return this.pause()
}
if (this.isCommenting) {
this.isCommenting = false
return
}
let el = e.target
let video = ''
if (el.nodeName == 'IMG') {
video = el.parentNode.previousSibling
} else { } else {
video = el.previousSibling this.play()
} }
video = this.$refs.video
if (video.paused) {
video.play()
} else {
video.pause()
}
this.isPlaying = !video.paused
}, },
loved(e, index) { loved(e, index) {
this.lVideo.isLoved = !this.lVideo.isLoved this.lVideo.isLoved = !this.lVideo.isLoved
this.$emit('update:video', this.lVideo) this.$emit('update:video', this.lVideo)
@ -280,8 +336,7 @@ export default {
move(e) { move(e) {
if (this.isPlaying) return if (this.isPlaying) return
this.isMove = true this.isMove = true
let video = this.$refs.video this.pause()
video.pause()
this.pageX = e.touches[0].pageX this.pageX = e.touches[0].pageX
// console.log(this.step) // console.log(this.step)
this.currentTime = Math.ceil(Math.ceil(e.touches[0].pageX) / this.step) this.currentTime = Math.ceil(Math.ceil(e.touches[0].pageX) / this.step)
@ -293,9 +348,8 @@ export default {
setTimeout(() => { setTimeout(() => {
this.isMove = false this.isMove = false
}, 1000) }, 1000)
let video = this.$refs.video this.currentTime = this.currentTime = Math.ceil(Math.ceil(e.changedTouches[0].pageX) / this.step)
video.currentTime = this.currentTime = Math.ceil(Math.ceil(e.changedTouches[0].pageX) / this.step) this.play()
video.play()
globalMethods.$stopPropagation(e) globalMethods.$stopPropagation(e)
} }
} }
@ -329,7 +383,7 @@ export default {
transform: scale(0); transform: scale(0);
} }
.bg-video { .video-wrapper {
position: relative; position: relative;
background: black; background: black;
font-size: 1.4rem; font-size: 1.4rem;
@ -342,18 +396,9 @@ export default {
/*position: absolute;*/ /*position: absolute;*/
} }
.float-container {
z-index: 1;
position: absolute;
top: 0;
width: 100%;
height: calc(100vh - 60px);
justify-content: center;
align-items: center;
.pause { .pause {
width: 60px; width: 4.5rem;
height: 60px; height: 4.5rem;
opacity: 0.5; opacity: 0.5;
position: absolute; position: absolute;
margin: auto; margin: auto;
@ -361,19 +406,38 @@ export default {
top: 0; top: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
animation: pause-animation 1.1s linear;
@scale: scale(1.2);
@keyframes pause-animation {
0% {
opacity: 0;
transform: scale(2);
}
10% {
opacity: 0.5;
transform: @scale;
}
100% {
transform: @scale;
opacity: 0.5;
}
}
} }
.float { .float {
position: absolute; position: absolute;
bottom: 0;
left: 0; left: 0;
top: 0;
height: 100%;
width: 100%; width: 100%;
display: flex;
flex-direction: column;
.normal { .normal {
position: absolute;
bottom: 1rem;
width: 100%;
transition: all .3s; transition: all .3s;
position: relative;
.toolbar { .toolbar {
//width: 40px; //width: 40px;
@ -455,82 +519,6 @@ export default {
background: red; background: red;
} }
.music-ctn {
position: relative;
.music-bg {
background-image: linear-gradient(black, #424242, black);
border-radius: 50%;
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
animation: animations 5s linear forwards infinite;
//display: none;
.music {
//display: none;
width: 25px;
height: 25px;
border-radius: 50%;
}
}
.music1, .music2 {
//display: none;
position: absolute;
width: 18px;
height: 18px;
top: 10px;
}
.music1 {
animation: anim-music1 2s linear forwards infinite;
}
.music2 {
animation: anim-music1 2s linear forwards infinite;
animation-delay: 1s;
}
}
@keyframes animations {
0% {
transform: rotate(0deg);;
}
100% {
transform: rotate(360deg);
}
}
@keyframes anim-music1 {
0% {
transform: translate3d(0, 0, 0);
opacity: 0;
}
20% {
transform: translate3d(-8px, 0px, 0) rotate(30deg);
opacity: .3;
}
40% {
transform: translate3d(-16px, -5px, 0) rotate(15deg);
opacity: .5;
}
60% {
transform: translate3d(-24px, -15px, 0) rotate(0deg);
opacity: 1;
}
80% {
transform: translate3d(-32px, -30px, 0) rotate(-15deg);
opacity: 1;
}
100% {
transform: translate3d(-32px, -50px, 0) rotate(-30deg);
opacity: 0;
}
}
} }
.content { .content {
@ -550,37 +538,6 @@ export default {
height: 20px; height: 20px;
margin-top: 3px; margin-top: 3px;
} }
marquee {
margin-left: 1rem;
}
.marquee {
color: white;
width: 100%;
overflow: hidden;
position: relative;
}
.marquee p {
margin: 0;
padding-left: 100%;
display: inline-block;
white-space: nowrap;
animation-name: marquee;
animation-timing-function: linear;
animation-duration: 5s;
animation-iteration-count: infinite;
}
@keyframes marquee {
from {
transform: translate(0%);
}
to {
transform: translate(-100%);
}
}
} }
} }
@ -665,14 +622,11 @@ export default {
} }
.process { .process {
//display: none; bottom: -1px;
//height: 20vh; position: absolute;
//width: 100vw; height: 7px;
height: 3px;
width: 100vw; width: 100vw;
background: black; background: black;
position: relative;
//bottom: 60px;
.time { .time {
@ -693,68 +647,51 @@ export default {
&:before { &:before {
z-index: 9; z-index: 9;
content: ' '; content: ' ';
height: 3.5px; height: 1.5px;
width: 100vw; width: 100vw;
background: gray; background: gray;
position: absolute; position: absolute;
top: -3px; top: 0;
} }
.line { .line {
z-index: 999; z-index: 999;
content: ''; content: '';
position: absolute; position: absolute;
top: -3px; top: 0;
height: 3px; height: 1px;
width: 200vw; width: 200vw;
transform: translate3d(-200vw, 0, 0); transform: translate3d(-200vw, 0, 0);
background: white; background: gray;
} }
.point { .point {
z-index: 10; z-index: 10;
position: absolute; position: absolute;
left: 10vw; left: 10vw;
top: -5px; top: -1px;
height: 8px; height: 4px;
width: 8px; width: 4px;
border-radius: 50%; border-radius: 50%;
background: white; background: gray;
} }
} }
& .stop { & .stop {
&:before { &:before {
z-index: 9; height: 3.5px;
content: ' ';
height: 1.5px;
width: 100vw;
background: #333333;
position: absolute;
top: -3px;
} }
.line { .line {
z-index: 999; height: 3px;
content: ''; background: white;
position: absolute;
top: -3px;
height: 1px;
width: 200vw;
transform: translate3d(-200vw, 0, 0);
background: gray;
} }
.point { .point {
z-index: 10; top: -2px;
position: absolute; height: 8px;
left: 10vw; width: 8px;
top: -4px; background: white;
height: 4px;
width: 4px;
border-radius: 50%;
background: gray;
}
} }
} }
} }

193
src/components/common/Music.vue

@ -1,193 +0,0 @@
<template>
<div class='Music'>
<header class="pl15p pr15p pt20p">
<div class="top pb20p d-flex justify-content-between">
<img src="../../assets/img/icon/next.svg" alt="" @click="back()">
<img src="../../assets/img/icon/share.svg" alt="">
</div>
<div class="bottom">
<img class="logo" src="../../assets/img/poster/src1-bg.png" alt="">
<div class="info">
<div class="name">MT创作的原声</div>
<div class="user">NT ></div>
<div class="peoples">1人使用</div>
<div class="collection">
<img src="../../assets/img/icon/collect-white.svg" alt="">
<span>收藏</span>
</div>
</div>
</div>
</header>
<div class="content">
<div class="tabs">
<div class="tab active" @click="toggleTab($event,0)">热门</div>
<div class="tab" @click="toggleTab($event,1)">最新</div>
</div>
<div class="video-container" v-for="(item,index) of videos" v-bind:style="{'height':width/3*1.2+'px'}">
<video src="../../assets/video/1.mp4" poster="../../assets/img/poster/src1-bg.png"></video>
<div class="no" v-if="index===1||index===2">
NO. <span>{{index+1}}</span>
</div>
<span v-if="index===0" class="first">首发</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Music",
components: {},
data() {
return {
videos: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
}
},
created() {
},
computed: {},
methods: {
toggleTab(e, index) {
if (!e.target.classList.contains('active')) {
e.target.classList.toggle('active')
}
if (index === 1) {
let pre = e.target.previousElementSibling
pre.classList.remove('active')
} else {
let pre = e.target.nextElementSibling
pre.classList.remove('active')
}
},
back() {
window.history.back()
}
}
}
</script>
<style scoped lang="less">
.Music {
header {
background: #454b66;
padding-bottom: 30px;
.top {
img {
width: 20px;
height: 20px;
&:nth-child(1) {
transform: rotate(180deg);
}
}
}
.bottom {
display: flex;
height: 120px;
.logo {
width: 120px;
height: 100%;
border-radius: 4px;
}
.info {
margin-left: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
.name {
font-size: 18px;
color: #fff;
font-weight: bold;
margin-bottom: 10px;
}
.user, .peoples {
margin-bottom: 5px;
color: #999999;
}
.collection {
display: flex;
justify-content: center;
height: 25px;
width: 80px;
align-items: center;
color: #ffffff;
background: #999;
border-radius: 2px;
img {
margin-right: 10px;
width: 15px;
height: 15px;
}
}
}
}
}
.content {
.tabs {
height: 40px;
display: flex;
align-items: center;
color: #fff;
.tab {
height: 90%;
width: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
&.active {
border-bottom: 3px solid yellow;
}
}
}
.video-container {
width: 33%;
float: left;
position: relative;
overflow: hidden;
border: .5px solid black;
video {
width: 100%;
}
.first {
padding: 0 5px;
border-radius: 4px;
position: absolute;
top: 10px;
left: 10px;
background: yellow;
}
.no {
position: absolute;
color: #bdbdbd;
bottom: 10px;
right: 10px;
font-style: italic;
span {
color: #ffffff;
font-size: 20px;
}
}
}
}
}
</style>

1
src/components/slide/SlideColumnVirtualList.vue

@ -118,6 +118,7 @@ export default {
}, },
methods: { methods: {
getInsEl(item, index, play = false) { getInsEl(item, index, play = false) {
// console.log('index',index,play)
let slideVNode = this.renderSlide(item, index, play) let slideVNode = this.renderSlide(item, index, play)
const app = Vue.createApp({ const app = Vue.createApp({
render() { render() {

3
src/pages/Test3.vue

@ -16,7 +16,7 @@ export default {
let id = 'a' + Date.now() let id = 'a' + Date.now()
let elWidth = 80 let elWidth = 80
let rotate = randomNum(0, 1) let rotate = randomNum(0, 1)
let template = `<img class="${rotate ? 'left' : 'right'}" id="${id}" src="${require('../assets/img/icon/loved.svg')}" alt="">` let template = `<img class="${rotate ? 'left love-dbclick' : 'right love-dbclick'}" id="${id}" src="${require('../assets/img/icon/loved.svg')}" alt="">`
let el = new Dom().create(template) let el = new Dom().create(template)
el.css({top: e.y - elWidth, left: e.x - elWidth / 2,}) el.css({top: e.y - elWidth, left: e.x - elWidth / 2,})
new Dom().find('.test').append(el) new Dom().find('.test').append(el)
@ -36,6 +36,7 @@ export default {
} }
} }
el.addEventListener('click', click) el.addEventListener('click', click)
// el.addEventListener('dblclick', click)
} }
} }
}, },

71
src/pages/Test4.vue

@ -1,27 +1,25 @@
<template> <template>
<div class="Test"> <div class="Test">
<div class="content1"> <div class="content1">
<div style="width: 50%;"> <BaseMarquee :is-play="true" :text="text" style="width: 150px;"/>
<div class="marquee"> <BaseButton @click="triggerPause">pause</BaseButton>
<span class="content">{{ text }}<span class="content-space"></span></span> <BaseButton @click="triggerStart">start</BaseButton>
</div>
</div>
<base-button @click="pause">stop</base-button>
<base-button @click="start">start</base-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import BaseButton from "../components/BaseButton"; import BaseButton from "../components/BaseButton";
import BaseMarquee from "../components/BaseMarquee";
import Dom from "../utils/dom";
export default { export default {
name: "Test4", name: "Test4",
components: {BaseButton}, components: {BaseButton, BaseMarquee},
props: { props: {
text: { text: {
type: String, type: String,
default: '跑马灯测试。跑马灯测试。跑马灯测试。' default: '@喵嗷污说电影创作的原声'
} }
}, },
data() { data() {
@ -33,35 +31,14 @@ export default {
} }
}, },
methods: { methods: {
pause() { triggerPause() {
cancelAnimationFrame(this.timer) new Dom('.text').trigger('pause')
},
triggerStart() {
new Dom('.text').trigger('start')
}, },
start() {
if (this.contentWidth <= 0) { //
return;
}
let fn = () => {
if (this.transformX > (-this.contentWidth / 3)) {
this.transformX -= 2
this.$marqueeContent.style.transform = `translate3d(${this.transformX}px,0,0)`
} else {
this.transformX = 0
}
this.timer = requestAnimationFrame(fn)
}
// this.timer = requestAnimationFrame(fn);
fn()
}
}, },
mounted() { mounted() {
let speed = 150; // -- px
let $marquee = document.querySelector('.marquee');
let $marqueeContent = this.$marqueeContent = $marquee.querySelector('.content');
// 3
$marqueeContent.innerHTML = $marqueeContent.innerHTML + $marqueeContent.innerHTML + $marqueeContent.innerHTML
this.contentWidth = $marqueeContent.getBoundingClientRect().width;
this.start()
} }
} }
</script> </script>
@ -82,30 +59,6 @@ export default {
.content1 { .content1 {
padding-top: 6rem; padding-top: 6rem;
.marquee {
width: 100%;
height: 4rem;
line-height: 4rem;
display: block;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
text-overflow: clip;
position: relative;
}
.marquee .content {
color: white;
display: inline-block;
position: relative;
white-space: nowrap;
}
.marquee .content-space {
display: inline-block;
width: 3rem;
}
} }

66
src/pages/Test5.vue

@ -0,0 +1,66 @@
<template>
<div class="Test">
<div class="content1">
<BaseMarquee :is-play="true" :text="text" style="width: 150px;"/>
<BaseButton @click="triggerPause">pause</BaseButton>
<BaseButton @click="triggerStart">start</BaseButton>
</div>
</div>
</template>
<script>
import BaseButton from "../components/BaseButton";
import BaseMarquee from "../components/BaseMarquee";
import Dom from "../utils/dom";
export default {
name: "Test4",
components: {BaseButton, BaseMarquee},
props: {
text: {
type: String,
default: '@喵嗷污说电影创作的原声'
}
},
data() {
return {
timer: null,
contentWidth: 0,
transformX: 0,
$marqueeContent: null,
}
},
methods: {
triggerPause() {
new Dom('.text').trigger('pause')
},
triggerStart() {
new Dom('.text').trigger('start')
},
},
mounted() {
}
}
</script>
<style scoped lang="less">
@import "../assets/scss/index";
.Test {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
font-size: 1.4rem;
color: white;
.content1 {
padding-top: 6rem;
}
}
</style>

107
src/pages/home/Index2.vue

@ -197,6 +197,7 @@ import BlockDialog from "../message/components/BlockDialog";
import Search from "../../components/Search"; import Search from "../../components/Search";
import ConfirmDialog from "../../components/dialog/ConfirmDialog"; import ConfirmDialog from "../../components/dialog/ConfirmDialog";
import FollowSetting2 from "./components/FollowSetting2"; import FollowSetting2 from "./components/FollowSetting2";
import Dom from "../../utils/dom";
export default { export default {
name: "HomeIndex", name: "HomeIndex",
@ -226,7 +227,7 @@ export default {
"cover": "https://p11.douyinpic.com/img/tos-cn-p-0015/48e513ae1df94a6cb0e23eabdacfdb64~c5_300x400.webp?from=4257465056_large", "cover": "https://p11.douyinpic.com/img/tos-cn-p-0015/48e513ae1df94a6cb0e23eabdacfdb64~c5_300x400.webp?from=4257465056_large",
"dynamic_cover": "https://p3.douyinpic.com/obj/tos-cn-p-0015/80e3288d63094603beaaf2f0e1568e19_1577426215?from=4257465056_large", "dynamic_cover": "https://p3.douyinpic.com/obj/tos-cn-p-0015/80e3288d63094603beaaf2f0e1568e19_1577426215?from=4257465056_large",
"origin_cover": "https://p3.douyinpic.com/tos-cn-p-0015/be6a2e67b69646778749e932c6d456b6_1577426215~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459040102120742003404DFC4&biz_tag=feed_cover", "origin_cover": "https://p3.douyinpic.com/tos-cn-p-0015/be6a2e67b69646778749e932c6d456b6_1577426215~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459040102120742003404DFC4&biz_tag=feed_cover",
video:mp40, video: mp40,
"video_data_size": 26829508, "video_data_size": 26829508,
"duration": 427780, "duration": 427780,
"desc": "几人到深山探险,发现里面一只动物昆虫都没有,知道原因后都怕了 #看电影", "desc": "几人到深山探险,发现里面一只动物昆虫都没有,知道原因后都怕了 #看电影",
@ -298,7 +299,7 @@ export default {
"cover": "https://p3.douyinpic.com/img/tos-cn-p-0015/9208072278a34d01b3836cce1e0fca9a~c5_300x400.jpeg?from=4257465056_large", "cover": "https://p3.douyinpic.com/img/tos-cn-p-0015/9208072278a34d01b3836cce1e0fca9a~c5_300x400.jpeg?from=4257465056_large",
"dynamic_cover": "https://p9.douyinpic.com/obj/tos-cn-p-0015/9208072278a34d01b3836cce1e0fca9a?from=4257465056_large", "dynamic_cover": "https://p9.douyinpic.com/obj/tos-cn-p-0015/9208072278a34d01b3836cce1e0fca9a?from=4257465056_large",
"origin_cover": "https://p3.douyinpic.com/tos-cn-p-0015/9ecfae1dda2141d19f3e2396d18c4f52_1610439608~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108311440160102120461454502506A&biz_tag=feed_cover", "origin_cover": "https://p3.douyinpic.com/tos-cn-p-0015/9ecfae1dda2141d19f3e2396d18c4f52_1610439608~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108311440160102120461454502506A&biz_tag=feed_cover",
video:mp41, video: mp41,
"video_data_size": 6038796, "video_data_size": 6038796,
"duration": 90927, "duration": 90927,
"desc": "几分钟看科幻片《寄生异种》 #我的观影报告 #抖音电影", "desc": "几分钟看科幻片《寄生异种》 #我的观影报告 #抖音电影",
@ -377,7 +378,7 @@ export default {
"cover": "https://p11.douyinpic.com/img/tos-cn-p-0015/3d6a0342b7f247ed999a13bd566b360e~c5_300x400.jpeg?from=4257465056_large", "cover": "https://p11.douyinpic.com/img/tos-cn-p-0015/3d6a0342b7f247ed999a13bd566b360e~c5_300x400.jpeg?from=4257465056_large",
"dynamic_cover": "https://p26.douyinpic.com/obj/tos-cn-p-0015/3d6a0342b7f247ed999a13bd566b360e?from=4257465056_large", "dynamic_cover": "https://p26.douyinpic.com/obj/tos-cn-p-0015/3d6a0342b7f247ed999a13bd566b360e?from=4257465056_large",
"origin_cover": "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/48891e08b43e47e2a3af9f3945cf941f_1607739586~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108311440220102120691615D029CD1&biz_tag=feed_cover", "origin_cover": "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/48891e08b43e47e2a3af9f3945cf941f_1607739586~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108311440220102120691615D029CD1&biz_tag=feed_cover",
video:mp42, video: mp42,
"video_data_size": 8996120, "video_data_size": 8996120,
"duration": 118703, "duration": 118703,
"desc": "美女失去记忆,被囚禁在密室内,没想到逃出去后才是她噩梦的开始 #我的观影报告", "desc": "美女失去记忆,被囚禁在密室内,没想到逃出去后才是她噩梦的开始 #我的观影报告",
@ -449,7 +450,7 @@ export default {
"cover": "https://p11.douyinpic.com/img/tos-cn-p-0015/c3bbe172b24844eb8e576a1897e04435~c5_300x400.webp?from=4257465056_large", "cover": "https://p11.douyinpic.com/img/tos-cn-p-0015/c3bbe172b24844eb8e576a1897e04435~c5_300x400.webp?from=4257465056_large",
"dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/12fc583b6eaa49b4a0086664c8f54a5d?from=4257465056_large", "dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/12fc583b6eaa49b4a0086664c8f54a5d?from=4257465056_large",
"origin_cover": "https://p26.douyinpic.com/tos-cn-p-0015/e7db9fba822c4d81b4ec4614f5c60cae~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459170102040221632C04B06F&biz_tag=feed_cover", "origin_cover": "https://p26.douyinpic.com/tos-cn-p-0015/e7db9fba822c4d81b4ec4614f5c60cae~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459170102040221632C04B06F&biz_tag=feed_cover",
video:mp43, video: mp43,
"video_data_size": 37824020, "video_data_size": 37824020,
"duration": 312474, "duration": 312474,
"desc": "夫妇二人来到一个诡异小镇,看到一个孩子的手,被吓到了 #看电影 ", "desc": "夫妇二人来到一个诡异小镇,看到一个孩子的手,被吓到了 #看电影 ",
@ -521,7 +522,7 @@ export default {
"cover": "https://p29.douyinpic.com/img/tos-cn-p-0015/1ce2018b919d49cfbdc380e9b7bc17ce~c5_300x400.jpeg?from=4257465056_large", "cover": "https://p29.douyinpic.com/img/tos-cn-p-0015/1ce2018b919d49cfbdc380e9b7bc17ce~c5_300x400.jpeg?from=4257465056_large",
"dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/1ce2018b919d49cfbdc380e9b7bc17ce?from=4257465056_large", "dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/1ce2018b919d49cfbdc380e9b7bc17ce?from=4257465056_large",
"origin_cover": "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/697621dc8ff247aba499fdaedcf172fb_1606272887~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=2021083114402801021219919632028316&biz_tag=feed_cover", "origin_cover": "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/697621dc8ff247aba499fdaedcf172fb_1606272887~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=2021083114402801021219919632028316&biz_tag=feed_cover",
video:mp44, video: mp44,
"video_data_size": 12371092, "video_data_size": 12371092,
"duration": 139652, "duration": 139652,
"desc": "茂密森林中却没有一个动物或昆虫,专家进去研究,被吓得转身就跑 #我的观影报告", "desc": "茂密森林中却没有一个动物或昆虫,专家进去研究,被吓得转身就跑 #我的观影报告",
@ -593,7 +594,7 @@ export default {
"cover": "https://p3.douyinpic.com/img/tos-cn-p-0015/3099e1f9facb4f11a8d07221b39b9ffb_1575186937~c5_300x400.webp?from=4257465056_large", "cover": "https://p3.douyinpic.com/img/tos-cn-p-0015/3099e1f9facb4f11a8d07221b39b9ffb_1575186937~c5_300x400.webp?from=4257465056_large",
"dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/f80ce3457bf34f66be9254df9544f9d8_1575186867?from=4257465056_large", "dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/f80ce3457bf34f66be9254df9544f9d8_1575186867?from=4257465056_large",
"origin_cover": "https://p11.douyinpic.com/tos-cn-p-0015/af2ef1dd2e864379a7a475b1db005b62_1575186867~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459070102112011425F04ED8F&biz_tag=feed_cover", "origin_cover": "https://p11.douyinpic.com/tos-cn-p-0015/af2ef1dd2e864379a7a475b1db005b62_1575186867~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459070102112011425F04ED8F&biz_tag=feed_cover",
video:mp45, video: mp45,
"video_data_size": 16916839, "video_data_size": 16916839,
"duration": 384068, "duration": 384068,
"desc": "男子在沙漠无意中召唤出可怕怪物,怪物的能力让他很绝望 #看电影", "desc": "男子在沙漠无意中召唤出可怕怪物,怪物的能力让他很绝望 #看电影",
@ -665,7 +666,7 @@ export default {
"cover": "https://p11.douyinpic.com/img/tos-cn-i-0004/b8d9811844d14f28a5d71b13ea30d89a~c5_300x400.jpeg?from=4257465056_large", "cover": "https://p11.douyinpic.com/img/tos-cn-i-0004/b8d9811844d14f28a5d71b13ea30d89a~c5_300x400.jpeg?from=4257465056_large",
"dynamic_cover": "https://p29.douyinpic.com/obj/tos-cn-i-0004/b8d9811844d14f28a5d71b13ea30d89a?from=4257465056_large", "dynamic_cover": "https://p29.douyinpic.com/obj/tos-cn-i-0004/b8d9811844d14f28a5d71b13ea30d89a?from=4257465056_large",
"origin_cover": "https://p11.douyinpic.com/tos-cn-p-0015/ac6b1eb1b6994ee1a284401f422f4d93_1627866958~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108301444360102111780824E10113C&biz_tag=feed_cover", "origin_cover": "https://p11.douyinpic.com/tos-cn-p-0015/ac6b1eb1b6994ee1a284401f422f4d93_1627866958~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108301444360102111780824E10113C&biz_tag=feed_cover",
video:mp46, video: mp46,
"video_data_size": 26944285, "video_data_size": 26944285,
"duration": 276000, "duration": 276000,
"desc": "2100年人口锐减,文明疯狂倒退,现今科技成了神话般的存在 #抖音电影#我的观影报告 ", "desc": "2100年人口锐减,文明疯狂倒退,现今科技成了神话般的存在 #抖音电影#我的观影报告 ",
@ -737,7 +738,7 @@ export default {
"cover": "https://p3.douyinpic.com/img/tos-cn-p-0015/bffc96dac41548d99a23e555d2bd3d62~c5_300x400.jpeg?from=4257465056_large", "cover": "https://p3.douyinpic.com/img/tos-cn-p-0015/bffc96dac41548d99a23e555d2bd3d62~c5_300x400.jpeg?from=4257465056_large",
"dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/bffc96dac41548d99a23e555d2bd3d62?from=4257465056_large", "dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/bffc96dac41548d99a23e555d2bd3d62?from=4257465056_large",
"origin_cover": "https://p1.douyinpic.com/tos-cn-p-0015/813c7bded67f4e3da0972f85be32eb3f_1608893061~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108311440220102120691615D029CD1&biz_tag=feed_cover", "origin_cover": "https://p1.douyinpic.com/tos-cn-p-0015/813c7bded67f4e3da0972f85be32eb3f_1608893061~tplv-dy-360p.jpeg?from=4257465056&s=&se=false&sh=&sc=&l=202108311440220102120691615D029CD1&biz_tag=feed_cover",
video:mp47, video: mp47,
"video_data_size": 9321536, "video_data_size": 9321536,
"duration": 129583, "duration": 129583,
"desc": "几分钟看科幻片《登月先锋》 #我的观影报告 #抖音电影", "desc": "几分钟看科幻片《登月先锋》 #我的观影报告 #抖音电影",
@ -816,7 +817,7 @@ export default {
"cover": "https://p9.douyinpic.com/img/tos-cn-p-0015/9f47c686c9224036b82f5c7b147e6119~c5_300x400.webp?from=4257465056_large", "cover": "https://p9.douyinpic.com/img/tos-cn-p-0015/9f47c686c9224036b82f5c7b147e6119~c5_300x400.webp?from=4257465056_large",
"dynamic_cover": "https://p26.douyinpic.com/obj/tos-cn-p-0015/fde5131f00e54106877d06f775cd21ca_1572239688?from=4257465056_large", "dynamic_cover": "https://p26.douyinpic.com/obj/tos-cn-p-0015/fde5131f00e54106877d06f775cd21ca_1572239688?from=4257465056_large",
"origin_cover": "https://p11.douyinpic.com/tos-cn-p-0015/8a757ad4df69407f8d0d443eaa0b60a2_1572239690~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459110102112011425F04EF3F&biz_tag=feed_cover", "origin_cover": "https://p11.douyinpic.com/tos-cn-p-0015/8a757ad4df69407f8d0d443eaa0b60a2_1572239690~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459110102112011425F04EF3F&biz_tag=feed_cover",
video:mp48, video: mp48,
"video_data_size": 25251313, "video_data_size": 25251313,
"duration": 449263, "duration": 449263,
"desc": "", "desc": "",
@ -888,7 +889,7 @@ export default {
"cover": "https://p5-ipv6.douyinpic.com/img/tos-cn-p-0015/1941731e18714268a52855ce869e3092_1572771120~c5_300x400.webp?from=4257465056_large", "cover": "https://p5-ipv6.douyinpic.com/img/tos-cn-p-0015/1941731e18714268a52855ce869e3092_1572771120~c5_300x400.webp?from=4257465056_large",
"dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/55b40ca5368a49eca282fb868c8fb98b_1572771083?from=4257465056_large", "dynamic_cover": "https://p11.douyinpic.com/obj/tos-cn-p-0015/55b40ca5368a49eca282fb868c8fb98b_1572771083?from=4257465056_large",
"origin_cover": "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/cd59468a8d0149aeb5291966004ae4e0_1572771088~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459110102112011425F04EF3F&biz_tag=feed_cover", "origin_cover": "https://p5-ipv6.douyinpic.com/tos-cn-p-0015/cd59468a8d0149aeb5291966004ae4e0_1572771088~tplv-dy-360p.webp?from=4257465056&s=&se=false&sh=&sc=&l=202108311459110102112011425F04EF3F&biz_tag=feed_cover",
video:mp49, video: mp49,
"video_data_size": 17839401, "video_data_size": 17839401,
"duration": 262127, "duration": 262127,
"desc": "灰姑娘被前男友羞辱,霸道总裁看不下去充当男友,瞬间让渣男无地自容#西瓜放映厅", "desc": "灰姑娘被前男友羞辱,霸道总裁看不下去充当男友,瞬间让渣男无地自容#西瓜放映厅",
@ -1180,12 +1181,13 @@ export default {
return ( return (
<div className="base-slide-item video-slide-item" data-index={itemIndex}> <div className="base-slide-item video-slide-item" data-index={itemIndex}>
<Video1 <Video1
play={play} isPlay={play}
video={item} video={item}
index={itemIndex} index={itemIndex}
onShowComments={e => this.isCommenting = true} onShowComments={e => this.isCommenting = true}
onShowShare={e => this.isSharing = true} onShowShare={e => this.isSharing = true}
onGoUserInfo={e => this.baseActiveIndex = 1} onGoUserInfo={e => this.baseActiveIndex = 1}
onGoMusic={e => this.$nav('/home/music')}
v-model={[this.videos[itemIndex], 'video']} v-model={[this.videos[itemIndex], 'video']}
/> />
</div> </div>
@ -1194,18 +1196,12 @@ export default {
} }
}, },
watch: { watch: {
videoActiveIndex(newVal) { videoActiveIndex(newVal, oldVal) {
$(".video-slide-item").each(function () { // console.log('videoActiveIndex', newVal, oldVal)
let video = $(this).find('video') new Dom(`.v-${newVal}-video`).trigger('play')
if ($(this).data('index') === newVal) {
video.trigger('play')
} else {
video.trigger('pause')
setTimeout(() => { setTimeout(() => {
video[0].currentTime = 0 new Dom(`.v-${oldVal}-video`).trigger('stop')
}, 100) }, 200)
}
})
if (newVal >= this.videos.length - 3 && newVal < this.totalSize) { if (newVal >= this.videos.length - 3 && newVal < this.totalSize) {
if (this.loading) return if (this.loading) return
this.pageNo++ this.pageNo++
@ -1233,6 +1229,7 @@ export default {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
this.totalSize = 11 this.totalSize = 11
// return this.videos = this.$clone(this.localVideos) // return this.videos = this.$clone(this.localVideos)
// await this.$sleep(200)
return this.videos = this.$clone(this.webVideos) return this.videos = this.$clone(this.webVideos)
} }
this.loading = true this.loading = true
@ -1255,11 +1252,75 @@ export default {
} }
} }
</script> </script>
<style scoped lang="less"> <style lang="less">
#home-index { #home-index {
height: 100%; height: 100%;
width: 100%; width: 100%;
//z-index: 4; //z-index: 4;
position: relative; position: relative;
.love-dbclick {
position: absolute;
@width: 8rem;
width: @width;
height: @width;
&.left {
animation: loveLeft 1.1s linear;
}
&.right {
animation: loveRight 1.1s linear;
}
@scale: scale(1.2);
@rotate: 10deg;
@keyframes loveLeft {
0% {
opacity: 0;
transform: scale(2) rotate(0-@rotate);
}
10% {
opacity: 1;
transform: scale(1) rotate(0-@rotate);
}
15% {
opacity: 1;
transform: @scale rotate(0-@rotate);
}
40% {
opacity: 1;
transform: @scale rotate(0-@rotate);
}
100% {
transform: translateY(-12rem) scale(2) rotate(0-@rotate);
opacity: 0;
}
}
@keyframes loveRight {
0% {
opacity: 0;
transform: scale(2) rotate(0+@rotate);
}
10% {
opacity: 1;
transform: scale(1) rotate(0+@rotate);
}
15% {
opacity: 1;
transform: @scale rotate(0+@rotate);
}
40% {
opacity: 1;
transform: @scale rotate(0+@rotate);
}
100% {
transform: translateY(-12rem) scale(2) rotate(0+@rotate);
opacity: 0;
}
}
}
} }
</style> </style>

199
src/pages/home/Music.vue

@ -0,0 +1,199 @@
<template>
<div class="Music">
<BaseHeader>
<template v-slot:center>
<span class="f16">申报学校信息</span>
</template>
<template v-slot:right>
<img src="../../assets/img/icon/share.svg" alt="">
</template>
</BaseHeader>
<div class="content">
<div class="bottom">
<img class="logo" src="../../assets/img/poster/src1-bg.png" alt="">
<div class="info">
<div class="name">MT创作的原声</div>
<div class="user">NT ></div>
<div class="peoples">1人使用</div>
<div class="collection">
<img src="../../assets/img/icon/collect-white.svg" alt="">
<span>收藏</span>
</div>
</div>
</div>
<div class="tabs">
<div class="tab active" @click="toggleTab($event,0)">热门</div>
<div class="tab" @click="toggleTab($event,1)">最新</div>
</div>
<div class="video-container" v-for="(item,index) of videos" v-bind:style="{'height':width/3*1.2+'px'}">
<video src="../../assets/video/1.mp4" poster="../../assets/img/poster/src1-bg.png"></video>
<div class="no" v-if="index===1||index===2">
NO. <span>{{ index + 1 }}</span>
</div>
<span v-if="index===0" class="first">首发</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Music",
components: {},
data() {
return {
videos: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
}
},
created() {
},
computed: {},
methods: {
toggleTab(e, index) {
if (!e.target.classList.contains('active')) {
e.target.classList.toggle('active')
}
if (index === 1) {
let pre = e.target.previousElementSibling
pre.classList.remove('active')
} else {
let pre = e.target.nextElementSibling
pre.classList.remove('active')
}
},
back() {
window.history.back()
}
}
}
</script>
<style scoped lang="less">
@import "../../assets/scss/index";
.Music {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
color: white;
font-size: 1.4rem;
img {
width: 2rem;
height: 2rem;
}
.content {
padding-top: 6rem;
.bottom {
display: flex;
height: 120px;
.logo {
width: 120px;
height: 100%;
border-radius: 4px;
}
.info {
margin-left: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
.name {
font-size: 18px;
color: #fff;
font-weight: bold;
margin-bottom: 10px;
}
.user, .peoples {
margin-bottom: 5px;
color: #999999;
}
.collection {
display: flex;
justify-content: center;
height: 25px;
width: 80px;
align-items: center;
color: #ffffff;
background: #999;
border-radius: 2px;
img {
margin-right: 10px;
width: 15px;
height: 15px;
}
}
}
}
.tabs {
height: 40px;
display: flex;
align-items: center;
color: #fff;
.tab {
height: 90%;
width: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
&.active {
border-bottom: 3px solid yellow;
}
}
}
.video-container {
width: 33%;
float: left;
position: relative;
overflow: hidden;
border: .5px solid black;
video {
width: 100%;
}
.first {
padding: 0 5px;
border-radius: 4px;
position: absolute;
top: 10px;
left: 10px;
background: yellow;
}
.no {
position: absolute;
color: #bdbdbd;
bottom: 10px;
right: 10px;
font-style: italic;
span {
color: #ffffff;
font-size: 20px;
}
}
}
}
}
</style>

4
src/router/index.js

@ -4,7 +4,7 @@ import Index from "../pages/home/Index";
import Attention from "../pages/home/Attention"; import Attention from "../pages/home/Attention";
import Message from "../pages/message/Message"; import Message from "../pages/message/Message";
import Me from "../pages/me/Me"; import Me from "../pages/me/Me";
import Music from "../components/common/Music"; import Music from "../pages/home/Music";
import countryChoose from "../pages/login/countryChoose"; import countryChoose from "../pages/login/countryChoose";
import MyCard from "../pages/me/MyCard"; import MyCard from "../pages/me/MyCard";
import MyCollect from "../pages/me/MyCollect"; import MyCollect from "../pages/me/MyCollect";
@ -61,6 +61,7 @@ const routes = [
{path: '/home', component: Index}, {path: '/home', component: Index},
{path: '/home/report', component: Report}, {path: '/home/report', component: Report},
{path: '/home/submit-report', component: SubmitReport}, {path: '/home/submit-report', component: SubmitReport},
{path: '/home/music', component: Music},
{path: '/attention', component: Attention}, {path: '/attention', component: Attention},
{path: '/publish', component: Publish}, {path: '/publish', component: Publish},
{path: '/message', component: Message}, {path: '/message', component: Message},
@ -72,7 +73,6 @@ const routes = [
{path: '/me/request-update', component: RequestUpdate}, {path: '/me/request-update', component: RequestUpdate},
{path: '/edit-userinfo', component: EditUserInfo}, {path: '/edit-userinfo', component: EditUserInfo},
{path: '/edit-userinfo-item', component: EditUserInfoItem}, {path: '/edit-userinfo-item', component: EditUserInfoItem},
{path: '/music', component: Music},
{path: '/country-choose', component: countryChoose}, {path: '/country-choose', component: countryChoose},
{path: '/my-card', component: MyCard}, {path: '/my-card', component: MyCard},
{path: '/my-collect', component: MyCollect}, {path: '/my-collect', component: MyCollect},

72
src/utils/dom.js

@ -1,11 +1,26 @@
export default class Dom { export default class Dom {
els = []
constructor() { constructor(arg) {
if (typeof arg === 'string') {
return this.find(arg)
}
if (typeof arg === 'object') {
this.els.push(arg)
}
if (typeof arg === 'function') {
document.addEventListener("DOMContentLoaded", arg);
}
return this
} }
find(tag) { find(tag) {
let els = document.querySelectorAll(tag) let els = []
if (this.els.length) {
els = this.els[0].querySelectorAll(tag)
} else {
els = document.querySelectorAll(tag)
}
if (els.length) { if (els.length) {
this.els = els this.els = els
} }
@ -21,7 +36,7 @@ export default class Dom {
append(that) { append(that) {
this.els.forEach(el => { this.els.forEach(el => {
that.els.map(v => { that.els.forEach(v => {
el.appendChild(v) el.appendChild(v)
}) })
}) })
@ -35,22 +50,57 @@ export default class Dom {
return this return this
} }
css(style, value = null) { css(...args) {
if (!value) { if (args.length === 1) {
Object.keys(style).map(key => { //情况一:获取样式
this.els.map(el => { if (typeof args[0] === 'string') {
el.style[key] = this.getStyleValue(key, style[key]) return this.els[0].style[args[0]]
} else {
//情况三:设置多个样式
Object.keys(args[0]).map(key => {
this.els.forEach(el => {
el.style[key] = this.getStyleValue(key, args[0][key])
}) })
} }
) )
}
} else { } else {
this.els.map(el => { //情况二,设置一对css样式
el.style[style] = this.getStyleValue(style, value) this.els.forEach(el => {
el.style[args[0]] = this.getStyleValue(args[0], args[1])
}) })
} }
return this return this
} }
on(eventName, fn) {
let eventArray = eventName.split(" ");
this.els.forEach(el => {
eventArray.map(event => {
el.addEventListener(event, fn);
})
})
return this;
}
trigger(eventName) {
let eventArray = eventName.split(" ");
this.els.forEach(el => {
eventArray.map(event => {
el.dispatchEvent(new Event(event));
})
})
return this;
}
getWidth() {
return this.els[0].getBoundingClientRect().width
}
getHeight() {
return this.els[0].getBoundingClientRect().height
}
getStyleValue(key, value) { getStyleValue(key, value) {
let whiteList = [ let whiteList = [
'top', 'top',

Loading…
Cancel
Save