提交 38ac698c 编写于 作者: 雪洛's avatar 雪洛

chore: 格式化代码

上级 a6d45c06
<template>
<view class="card" ref="card" @touchstart="touchstart($event as TouchEvent)"
@touchmove="touchmove($event as TouchEvent)" @touchend="touchend" @touchcancel="touchend">
<image class="card-img" ref="card-img" :src="img"></image>
<view class="state">
<image class="state-icon like" ref="state-icon-like" src="/static/template/drop-card/like.png" mode="widthFix">
</image>
<image class="state-icon dislike" ref="state-icon-dislike" src="/static/template/drop-card/dislike.png"
mode="widthFix"></image>
<!-- cardIndex:{{cardIndex}} -->
</view>
<view class="card" ref="card" @touchstart="touchstart($event as TouchEvent)"
@touchmove="touchmove($event as TouchEvent)" @touchend="touchend" @touchcancel="touchend">
<image class="card-img" ref="card-img" :src="img"></image>
<view class="state">
<image class="state-icon like" ref="state-icon-like" src="/static/template/drop-card/like.png" mode="widthFix">
</image>
<image class="state-icon dislike" ref="state-icon-dislike" src="/static/template/drop-card/dislike.png"
mode="widthFix"></image>
<!-- cardIndex:{{cardIndex}} -->
</view>
</view>
</template>
<script>
let sX : number = 0,
......@@ -21,22 +21,22 @@
export default {
data() {
return {
$elementMap:new Map<string, Element>(),
$elementMap: new Map<string, Element>(),
x: 0 as number,
y: 0 as number,
// 飘走的卡片计数
floatCount:0 as number
y: 0 as number,
// 飘走的卡片计数
floatCount: 0 as number
}
},
props: {
img: {
type: String,
default: "/static/template/drop-card/1.jpg"
},
cardIndex:{
type:Number,
default:0
}
},
cardIndex: {
type: Number,
default: 0
}
},
computed: {
movePercent() : number {
......@@ -47,47 +47,47 @@
},
dislikeOpacity() : number {
return this.x > 0 ? 0 : this.movePercent * 100
}
},
mounted() {
uni.getSystemInfo({
success: (e) => {
screenWidth = e.screenWidth;
screenHeight = e.screenHeight;
}
})
// TODO 需要延迟设置才能生效
setTimeout(()=>{
this.setElementStyle('card','height', screenHeight * 0.7 + 'px');
this.setElementStyle('card-img','height', screenHeight * 0.7 + 'px');
this.initCardStyle()
},200)
uni.$on('uni-drop-card-float',()=>{
this.floatCount ++
this.initCardStyle()
})
}
},
methods: {
initCardStyle(){
let _index = (this.cardIndex + this.floatCount)%3
// console.log('~~~~~~_index:'+_index + ' cardIndex:'+this.cardIndex+' floatCount:'+this.floatCount);
this.setElementStyle('card','z-index', _index)
this.setElementStyle('card','margin-top', screenHeight * 0.15 - 30 * _index + 'px');
this.setElementStyle('card','transform', 'scale('+(0.9 + 0.05 * _index)+')')
},
mounted() {
uni.getSystemInfo({
success: (e) => {
screenWidth = e.screenWidth;
screenHeight = e.screenHeight;
}
})
// TODO 需要延迟设置才能生效
setTimeout(() => {
this.setElementStyle('card', 'height', screenHeight * 0.7 + 'px');
this.setElementStyle('card-img', 'height', screenHeight * 0.7 + 'px');
this.initCardStyle()
}, 200)
uni.$on('uni-drop-card-float', () => {
this.floatCount++
this.initCardStyle()
})
},
methods: {
initCardStyle() {
let _index = (this.cardIndex + this.floatCount) % 3
// console.log('~~~~~~_index:'+_index + ' cardIndex:'+this.cardIndex+' floatCount:'+this.floatCount);
this.setElementStyle('card', 'z-index', _index)
this.setElementStyle('card', 'margin-top', screenHeight * 0.15 - 30 * _index + 'px');
this.setElementStyle('card', 'transform', 'scale(' + (0.9 + 0.05 * _index) + ')')
},
// 工具方法,用于快速设置 Element 的 style
setElementStyle(refName:string,propertyName : string, propertyStyle : any) : void {
setElementStyle(refName : string, propertyName : string, propertyStyle : any) : void {
const elementMap = this.$data['$elementMap'] as Map<string, Element>
let element : Element | null = elementMap[refName]
if(element == null){
element = this.$refs[refName] as Element;
elementMap[refName] = element
}else{
// console.log('直接拿');
}
let element : Element | null = elementMap[refName]
if (element == null) {
element = this.$refs[refName] as Element;
elementMap[refName] = element
} else {
// console.log('直接拿');
}
element?.style?.setProperty(propertyName, propertyStyle);
},
touchstart(e : TouchEvent) {
......@@ -114,85 +114,85 @@
this.moveCard()
},
touchend() {
// console.log('touchend')
touchstartAfter = false
if(floating){
return // 浮动动画进行中
}
floating = true
// 设置释放之后飘走的方向 0回到坐标中心 1向右 2向左
let k:number = 0;
if (this.x > screenWidth / 10 ) {
k = 1
}else if(this.x < screenWidth * -1 / 10){
k = -1
}
function cardTo(x:number,y:number,callback: () => void,speed:number = 10){
let interval:number = 0
let acceleration:number = 1
interval = setInterval(()=>{
// 加速度
acceleration += 0.2
const dx = x - this.x
if(Math.abs(dx) < 1){
this.x = x
}else{
this.x += dx/speed*acceleration
}
const dy = y - this.y
if(Math.abs(dy) < 1){
this.y = y
}else{
this.y += dy/speed*acceleration
}
this.moveCard()
if( this.x == x && this.y == y){
clearInterval(interval)
callback()
}
},16)
}
if(k.toInt() != 0){
cardTo(k * screenWidth * 1.3, this.y * 3,()=>{
// 状态图标变回透明
this.setElementStyle("state-icon-like",'opacity', 0)
this.setElementStyle("state-icon-dislike",'opacity', 0)
// 设置为透明,防止飘回时因为 margin-top 太高,露出来
this.setElementStyle("card",'opacity', 0)
setTimeout(()=>{
this.setElementStyle("card",'opacity', 1)
},300)
// 执行卡片飘动后事件,注意uni.$emit是全局事件。其他卡片也会执行
uni.$emit('uni-drop-card-float',null)
floating = false
},8)
}else{
const _x:number = this.x
const _y:number = this.y
cardTo( (_x*-0.05).toInt() , (_y*-0.05).toInt() ,()=>{
cardTo(0,0,()=>{
console.log('bounce')
floating = false
},30)
})
}
},
// console.log('touchend')
touchstartAfter = false
if (floating) {
return // 浮动动画进行中
}
floating = true
// 设置释放之后飘走的方向 0回到坐标中心 1向右 2向左
let k : number = 0;
if (this.x > screenWidth / 10) {
k = 1
} else if (this.x < screenWidth * -1 / 10) {
k = -1
}
function cardTo(x : number, y : number, callback : () => void, speed : number = 10) {
let interval : number = 0
let acceleration : number = 1
interval = setInterval(() => {
// 加速度
acceleration += 0.2
const dx = x - this.x
if (Math.abs(dx) < 1) {
this.x = x
} else {
this.x += dx / speed * acceleration
}
const dy = y - this.y
if (Math.abs(dy) < 1) {
this.y = y
} else {
this.y += dy / speed * acceleration
}
this.moveCard()
if (this.x == x && this.y == y) {
clearInterval(interval)
callback()
}
}, 16)
}
if (k.toInt() != 0) {
cardTo(k * screenWidth * 1.3, this.y * 3, () => {
// 状态图标变回透明
this.setElementStyle("state-icon-like", 'opacity', 0)
this.setElementStyle("state-icon-dislike", 'opacity', 0)
// 设置为透明,防止飘回时因为 margin-top 太高,露出来
this.setElementStyle("card", 'opacity', 0)
setTimeout(() => {
this.setElementStyle("card", 'opacity', 1)
}, 300)
// 执行卡片飘动后事件,注意uni.$emit是全局事件。其他卡片也会执行
uni.$emit('uni-drop-card-float', null)
floating = false
}, 8)
} else {
const _x : number = this.x
const _y : number = this.y
cardTo((_x * -0.05).toInt(), (_y * -0.05).toInt(), () => {
cardTo(0, 0, () => {
console.log('bounce')
floating = false
}, 30)
})
}
},
moveCard() {
this.setElementStyle("card",
this.setElementStyle("card",
'transform',
`translate(${this.x}px,${this.y}px) rotate(${this.x/-30}deg) scale(1)`
)
this.setElementStyle("state-icon-like",'opacity', this.x < 0 ? 0 : this.movePercent * 10)
this.setElementStyle("state-icon-dislike",'opacity', this.x > 0 ? 0 : this.movePercent * 10)
}
`translate(${this.x}px,${this.y}px) rotate(${this.x / -30}deg) scale(1)`
)
this.setElementStyle("state-icon-like", 'opacity', this.x < 0 ? 0 : this.movePercent * 10)
this.setElementStyle("state-icon-dislike", 'opacity', this.x > 0 ? 0 : this.movePercent * 10)
}
}
}
</script>
......@@ -210,7 +210,7 @@
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
background-color: #FFF;
transition: margin-top 300ms;
transition-timing-function: ease-in;
transition-timing-function: ease-in;
}
.card-img {
......@@ -239,4 +239,4 @@
box-shadow: 0 0 1px #EBEBEB;
opacity: 0;
}
</style>
</style>
\ No newline at end of file
<template>
<view class="page">
<view @click="back" class="nav-back">
<image class="back-img" src="/static/template/scroll-fold-nav/back.png" mode="widthFix"></image>
</view>
<swiper class="swiper" :current="current" :circular="index != 0" :vertical="true" @change="onSwiperChange" @transition="onTransition">
<swiper-item class="swiper-item" v-for="(item,i) in visibleList" :key="i">
<video @click="changeState(i)" ref="video" class="video-box" objectFit="cover" :id="'video-'+i"
@loadstart="onLoadstart(i)" :src="item.src" :poster="item.poster_src"
:autoplay="false" :show-center-play-btn="false"
:loop="true" @play="onPlay(i)" @pause="onPause(i)"
></video>
<view class="video-cover" @click="changeState(i)">
<image v-if="state[i] === 'pause'" class="play-btn" src="/static/template/swiper-vertical-video/play.png" mode="widthFix"></image>
</view>
<view class="video-info" v-if="0">
<text class="video-info-text">容器:第 {{i}} 个</text>
<text class="video-info-text">内容:{{item.content}}</text>
</view>
</swiper-item>
</swiper>
<view class="debug-info" v-if="0">
<view class="page">
<view @click="back" class="nav-back">
<image class="back-img" src="/static/template/scroll-fold-nav/back.png" mode="widthFix"></image>
</view>
<swiper class="swiper" :current="current" :circular="index != 0" :vertical="true" @change="onSwiperChange"
@transition="onTransition">
<swiper-item class="swiper-item" v-for="(item,i) in visibleList" :key="i">
<video @click="changeState(i)" ref="video" class="video-box" objectFit="cover" :id="'video-'+i"
@loadstart="onLoadstart(i)" :src="item.src" :poster="item.poster_src" :autoplay="false"
:show-center-play-btn="false" :loop="true" @play="onPlay(i)" @pause="onPause(i)"></video>
<view class="video-cover" @click="changeState(i)">
<image v-if="state[i] === 'pause'" class="play-btn" src="/static/template/swiper-vertical-video/play.png"
mode="widthFix"></image>
</view>
<view class="video-info" v-if="0">
<text class="video-info-text">容器:第 {{i}} 个</text>
<text class="video-info-text">内容:{{item.content}}</text>
</view>
</swiper-item>
</swiper>
<view class="debug-info" v-if="0">
<text class="status-text">debug-info 播放状态:</text>
<text class="status-text" v-for="(value,index) in state">第{{index+1}}个:{{ value }}</text>
</view>
</view>
</view>
</template>
<script>
type ListItem = { _id : string, content : string, src : string, poster_src : string }
let page : number = 0,
currentPageIsShow : boolean = true;
type ListItem = { _id : string, content : string, src : string, poster_src : string }
let page : number = 0,
currentPageIsShow : boolean = true;
export default {
components: {},
data() {
return {
export default {
components: {},
data() {
return {
$videoContextMap: new Map<string, VideoContext>(),
list: [] as ListItem[],
visibleList: [] as ListItem[],// 提高性能 可见的只有3个
current: 0 as number,
index: 0,
state: ["unPlay", "unPlay", "unPlay"] as string[]
}
},
created() {
this.list = this.getData()
this.visibleList = this.list.slice(0, 3)
},
watch: {
current(current : number, oldCurrent : number) {
let changeNumber = current - oldCurrent
if (changeNumber == 1 || changeNumber == -2) {
// console.error('向右');
this.index++
} else {
// console.error('向左');
this.index--
}
// //翻页(3项为一页)
if (Math.abs(changeNumber) == 2) {
// console.log('翻页');
page = Math.floor(this.index / 3);
// console.log(this.index);
// console.log('page',page);
// console.log('slice',3*page,3*page+3);
if (this.list.length < 3 * page + 3) {
let list : ListItem[] = this.getData()
this.list.push(...list)
}
list: [] as ListItem[],
visibleList: [] as ListItem[],// 提高性能 可见的只有3个
current: 0 as number,
index: 0,
state: ["unPlay", "unPlay", "unPlay"] as string[]
}
},
created() {
this.list = this.getData()
this.visibleList = this.list.slice(0, 3)
},
watch: {
current(current : number, oldCurrent : number) {
let changeNumber = current - oldCurrent
if (changeNumber == 1 || changeNumber == -2) {
// console.error('向右');
this.index++
} else {
// console.error('向左');
this.index--
}
// //翻页(3项为一页)
if (Math.abs(changeNumber) == 2) {
// console.log('翻页');
page = Math.floor(this.index / 3);
// console.log(this.index);
// console.log('page',page);
// console.log('slice',3*page,3*page+3);
if (this.list.length < 3 * page + 3) {
let list : ListItem[] = this.getData()
this.list.push(...list)
}
let visibleList = this.list.slice(3 * page, 3 * page + 3)
// 换数据
this.visibleList = visibleList
}
this.state.forEach((_ : string, index : number) => {
if (index === current) {
this.doPlay(current)
} else {
// 除了选中的其他已经播放的都需要停止
this.doStop(index)
console.log('index:' + index + '已被执行停止');
}
})
}
},
onReady() {
// 一启动完成,就播放第一个
this.doPlay(0)
},
onShow(){
currentPageIsShow = true
},
onHide() {
currentPageIsShow = false
console.log('pages-onHide');
this.doPause(this.current)
},
onUnload() {
this.doPause(this.current)
let visibleList = this.list.slice(3 * page, 3 * page + 3)
// 换数据
this.visibleList = visibleList
}
this.state.forEach((_ : string, index : number) => {
if (index === current) {
this.doPlay(current)
} else {
// 除了选中的其他已经播放的都需要停止
this.doStop(index)
console.log('index:' + index + '已被执行停止');
}
})
}
},
onReady() {
// 一启动完成,就播放第一个
this.doPlay(0)
},
onShow() {
currentPageIsShow = true
},
onHide() {
currentPageIsShow = false
console.log('pages-onHide');
this.doPause(this.current)
},
methods: {
changeState(index : number) {
if (this.state[index] === 'play') {
this.doPause(index)
} else {
this.doPlay(this.current)
}
},
onLoadstart(index : number) {
console.error("onLoadstart video" + index );
},
getVideoContext(index : number) : VideoContext {
const videoContextMap = this.$data['$videoContextMap'] as Map<string, VideoContext>
let videoContext : VideoContext | null = videoContextMap['video-'+index]
if(videoContext == null){
videoContext = uni.createVideoContext('video-'+index, this) as VideoContext
videoContextMap['video-'+index] = videoContext
}
return videoContext
onUnload() {
this.doPause(this.current)
},
methods: {
changeState(index : number) {
if (this.state[index] === 'play') {
this.doPause(index)
} else {
this.doPlay(this.current)
}
},
onLoadstart(index : number) {
console.error("onLoadstart video" + index);
},
getVideoContext(index : number) : VideoContext {
const videoContextMap = this.$data['$videoContextMap'] as Map<string, VideoContext>
let videoContext : VideoContext | null = videoContextMap['video-' + index]
if (videoContext == null) {
videoContext = uni.createVideoContext('video-' + index, this) as VideoContext
videoContextMap['video-' + index] = videoContext
}
return videoContext
},
doPlay(index : number) {
console.log("doPlay video" + index );
this.getVideoContext(index).play()
},
doStop(index : number) {
console.log("doStop video-" + index);
this.getVideoContext(index).stop();
// TODO 临时方案:解决.stop()时触发了doPause的问题
setTimeout(()=>{
this.state[index] = 'unPlay'
},1000)
},
doPause(index : number) {
this.getVideoContext(index).pause()
console.log("doPause video-" + index);
doPlay(index : number) {
console.log("doPlay video" + index);
this.getVideoContext(index).play()
},
onPause(index : number) {
this.state[index] = 'pause'
console.log('onPause', index);
},
onPlay(index : number) {
if(this.current != index || !currentPageIsShow){
this.onPause(index)
}else{
this.state[index] = 'play'
console.log('onPlay', index);
doStop(index : number) {
console.log("doStop video-" + index);
this.getVideoContext(index).stop();
// TODO 临时方案:解决.stop()时触发了doPause的问题
setTimeout(() => {
this.state[index] = 'unPlay'
}, 1000)
},
doPause(index : number) {
this.getVideoContext(index).pause()
console.log("doPause video-" + index);
},
onPause(index : number) {
this.state[index] = 'pause'
console.log('onPause', index);
},
onPlay(index : number) {
if (this.current != index || !currentPageIsShow) {
this.onPause(index)
} else {
this.state[index] = 'play'
console.log('onPlay', index);
}
},
getData() : ListItem[] {
let videoUrlList = [
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uts.mp4',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-ai.mp4',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-verify.mp4'
] as string[]
},
getData() : ListItem[] {
let videoUrlList = [
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uts.mp4',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-ai.mp4',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-verify.mp4'
] as string[]
let posterSrcList = [
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-uts.jpg',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-ai.jpg',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-verify.jpg'
] as string[]
let posterSrcList = [
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-uts.jpg',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-ai.jpg',
'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-verify.jpg'
] as string[]
let list = [] as ListItem[];
for (let i = 0; i < 6; i++) {
let index = this.list.length + i;
let listItem : ListItem = {
"_id": "a00" + index,
"content": "这是第" + index + "条数据,url地址" + videoUrlList[i % 3],
"src": videoUrlList[i % 3],
"poster_src": posterSrcList[i % 3]
}
list.push(listItem)
}
return list
},
onSwiperChange(e : SwiperChangeEvent) {
// console.error('SwiperChangeEvent',e.detail.current);
this.current = e.detail.current;
},
onTransition(/*e : SwiperTransitionEvent*/) {
// console.log('onTransition e.detail.dx', e.detail.dx);
},
back() {
uni.navigateBack({
success(result) {
console.log('navigateBack success', result.errMsg)
},
fail(error) {
console.log('navigateBack fail', error.errMsg)
},
complete(result) {
console.log('navigateBack complete', result.errMsg)
}
})
let list = [] as ListItem[];
for (let i = 0; i < 6; i++) {
let index = this.list.length + i;
let listItem : ListItem = {
"_id": "a00" + index,
"content": "这是第" + index + "条数据,url地址" + videoUrlList[i % 3],
"src": videoUrlList[i % 3],
"poster_src": posterSrcList[i % 3]
}
list.push(listItem)
}
return list
},
onSwiperChange(e : SwiperChangeEvent) {
// console.error('SwiperChangeEvent',e.detail.current);
this.current = e.detail.current;
},
onTransition(/*e : SwiperTransitionEvent*/) {
// console.log('onTransition e.detail.dx', e.detail.dx);
},
back() {
uni.navigateBack({
success(result) {
console.log('navigateBack success', result.errMsg)
},
fail(error) {
console.log('navigateBack fail', error.errMsg)
},
complete(result) {
console.log('navigateBack complete', result.errMsg)
}
})
}
}
}
}
}
</script>
<style>
.page {
width: 750rpx;
.page {
width: 750rpx;
flex: 1;
}
}
.swiper,
.swiper-item,
.video-box,
.video-cover {
width:750rpx;
flex: 1;
height: 100%;
}
.swiper,
.swiper-item,
.video-box,
.video-cover {
width: 750rpx;
flex: 1;
height: 100%;
}
.swiper-item {
position: relative;
}
.swiper-item {
position: relative;
}
.video-box {
width: 750rpx;
.video-box {
width: 750rpx;
}
.video-cover {
.video-cover {
position: absolute;
justify-content: center;
align-items: center;
align-content: center;
}
.play-btn {
width: 80rpx;
height: 80rpx;
justify-content: center;
align-items: center;
align-content: center;
}
.video-info {
position: absolute;
bottom: 0;
padding: 15px;
}
.play-btn {
width: 80rpx;
height: 80rpx;
}
.video-info-text {
font-size: 14px;
color: red;
line-height: 20px;
}
.video-info {
position: absolute;
bottom: 0;
padding: 15px;
}
.debug-info{
position: fixed;
top:15px;
width: 750rpx;
background-color: rgba(255, 255, 255, 0.3);
}
.status-text{
color:red;
padding: 15px;
}
.nav-back {
position: absolute;
top: 20px;
left: 8px;
background-color: rgba(220, 220, 220, 0.8);
border-radius: 100px;
width: 28px;
height: 28px;
justify-content: center;
align-items: center;
z-index: 10;
}
.nav-back .back-img {
width: 18px;
height: 18px;
}
</style>
.video-info-text {
font-size: 14px;
color: red;
line-height: 20px;
}
.debug-info {
position: fixed;
top: 15px;
width: 750rpx;
background-color: rgba(255, 255, 255, 0.3);
}
.status-text {
color: red;
padding: 15px;
}
.nav-back {
position: absolute;
top: 20px;
left: 8px;
background-color: rgba(220, 220, 220, 0.8);
border-radius: 100px;
width: 28px;
height: 28px;
justify-content: center;
align-items: center;
z-index: 10;
}
.nav-back .back-img {
width: 18px;
height: 18px;
}
</style>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册