<template>
<view class="cardsVw">
<scroll-view class="scrollView"
:scroll-y="true"
@scroll="handleContainerScroll"
>
<view class="cardVw" v-for="(item,index) in dataList" :index="index">
<view class="headerVw">
<view class="avatar">
<!-- <image src="@/static/component/videoImagePage/avatar.jpg" mode=""></image> -->
<image :src="item.avatar" mode=""></image>
</view>
<view class="nameTime">
<p class="name">{{item.name}}</p>
<p class="time">{{item.time}} · {{item.region}}</p>
</view>
</view>
<view class="textVw">
{{item.text}}
</view>
<view class="videoVw" v-if="item.videoBool">
<video src="@/static/component/videoImagePage/video.mp4"
object-fit="cover"
:danmu-btn="true"
:danmu-list="item.danmuList"
:ref="el => setVideoRef(el, index)"
:id="`video-${index}`"
:show-mute-btn="true"
muted
playsinline
></video>
</view>
<view class="imageVw" v-if="item.imageBool">
</view>
<view class="likeVw">
<view class="btnVw" @click="likeFun(item)">
<image v-if="!item.likeBool" src="@/static/component/videoImagePage/xh.png" mode=""></image>
<image v-else src="@/static/component/videoImagePage/xhxz.png" mode=""></image>
<p>{{item.like}}</p>
</view>
<view class="btnVw">
<image src="@/static/component/videoImagePage/pl.png" mode=""></image>
<p>{{item.comment}}</p>
</view>
<view class="btnVw" @click="collectFun(item)">
<image v-if="!item.collectBool" src="@/static/component/videoImagePage/sc.png" mode=""></image>
<image v-else src="@/static/component/videoImagePage/scxz.png" mode=""></image>
<p>{{item.collect}}</p>
</view>
<view class="btnVw">
<image src="@/static/component/videoImagePage/fx.png" mode=""></image>
<p>{{item.share}}</p>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import { ref, reactive, onMounted, nextTick } from "vue";
import { useStore } from "vuex";
export default {
setup() {
const store = useStore()
const videoRef = ref(null)
const dataList = ref([
{
avatar:'https://img2.baidu.com/it/u=2747463332,607814380&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=949',
name:'陈伟霆',
time:'2小时前',
region:'上海',
text:'今天的天气真不错,周末徒步遇到彩虹实在太幸运了。爬到山顶的时候刚好遇到雨过天晴,山谷间架起一道完整的彩虹。徒步虽然累但看到这样的风景一切都值得!',
videoBool:true,
videoUrl:'https://vdept3.bdstatic.com/mda-qh7bz8ruth00v0wh/360p/h264/1723105705960892507/mda-qh7bz8ruth00v0wh.mp4?v_from_s=hkapp-haokan-nanjing&auth_key=1761304717-0-0-63cd78d8e3f85fca3ae5ef599458d025&bcevod_channel=searchbox_feed&pd=1&cr=0&cd=0&pt=3&logid=1117309092&vid=3793288057898252473&klogid=1117309092&abtest=',
imageBool:false,
imageUrl:[],
like:23,
comment:60,
collect:54,
likeBool:true,
collectBool:true,
share:130,
danmuList:[
{
text: "这剧太好看了!", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 1.2, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "男主好帅!",
color: "#FF0000", // 红色弹幕
time: 3.5,
userId: "user_456",
nickname: "颜控一枚",
position: "top" // 自定义字段:顶部固定(需配合前端逻辑实现)
},
{
text: "天空好美啊~~~~", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 5.8, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "真惬意啊!!", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 7.5, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "有没有组队去的", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 10, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "是时候拿出我的大疆Poket3来拍摄了", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 13, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
]
},
{
avatar:'https://img0.baidu.com/it/u=774324087,3529403915&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=751',
name:'张杰',
time:'7小时前',
region:'北京',
text:'欢迎大家来参加我北京的演唱会,我在北京鸟巢等你们哦!',
videoBool:true,
videoUrl:'@/static/component/videoImagePage/video.mp4',
imageBool:false,
imageUrl:[],
like:88,
comment:150,
collect:378,
share:654,
likeBool:true,
collectBool:false,
danmuList:[
{
text: "这剧太好看了!", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 1.2, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "男主好帅!",
color: "#FF0000", // 红色弹幕
time: 3.5,
userId: "user_456",
nickname: "颜控一枚",
position: "top" // 自定义字段:顶部固定(需配合前端逻辑实现)
},
{
text: "天空好美啊~~~~", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 5.8, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "真惬意啊!!", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 7.5, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "有没有组队去的", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 10, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "是时候拿出我的大疆Poket3来拍摄了", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 13, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
]
},
{
avatar:'https://image.huanghepiao.com/d/file/20230630/3b662a34bb4aec8343e316fa1946ff61.jpg',
name:'薛之谦',
time:'12小时前',
region:'北京',
text:'想我了 要在网上跟我说什么!',
videoBool:true,
videoUrl:'@/static/component/videoImagePage/video.mp4',
imageBool:false,
imageUrl:[],
like:96,
comment:243,
collect:399,
share:717,
likeBool:false,
collectBool:true,
danmuList:[
{
text: "这剧太好看了!", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 1.2, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "男主好帅!",
color: "#FF0000", // 红色弹幕
time: 3.5,
userId: "user_456",
nickname: "颜控一枚",
position: "top" // 自定义字段:顶部固定(需配合前端逻辑实现)
},
{
text: "天空好美啊~~~~", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 5.8, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "真惬意啊!!", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 7.5, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "有没有组队去的", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 10, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
{
text: "是时候拿出我的大疆Poket3来拍摄了", // 弹幕文本(必选,组件默认字段名是 text,不是 content)
color: "#FFFFFF", // 弹幕颜色(必选,默认白色,支持十六进制/RGB)
time: 13, // 出现时间(必选,单位:秒,对应视频播放到1.2秒时显示)
// 以下为自定义扩展字段(可选)
userId: "user_123", // 发送者ID
nickname: "追剧达人", // 发送者昵称
fontSize: 14 // 字体大小(部分组件支持,默认14px)
},
]
},
])
const likeFun = (item) => {
item.likeBool = !item.likeBool
if(item.likeBool){
item.like += 1
}else{
item.like -= 1
}
}
const collectFun = (item) => {
item.collectBool = !item.collectBool
if(item.collectBool){
item.collect += 1
uni.$u.toast('已收藏');
}else{
item.collect -= 1
}
}
const videoRefs = ref([])
const setVideoRef = (el, index) => {
if (el) {
videoRefs.value[index] = el
}
}
const calculateBottomDistances = () => {
dataList.value.forEach((item, index) => {
// 使用uni-app的节点查询
const query = uni.createSelectorQuery()
query.select(`#video-${index}`).boundingClientRect(data => {
if (!data) return
uni.getSystemInfo({
success: (sys) => {
// 计算距离底部位置(窗口高度 - (节点top + 节点高度))
const bottomDistance = sys.windowHeight - (data.top + data.height)
// 更新到对应的视频数据中
item.bottomDistance = bottomDistance
console.log(`视频${index}距离底部: ${bottomDistance}px`)
if(bottomDistance < 410 && bottomDistance > 70){
}else{
}
}
})
}).exec()
})
}
const handleContainerScroll = () => {
// console.log(videoRefs.value)
calculateBottomDistances()
}
onMounted(()=>{
setTimeout(calculateBottomDistances, 100)
})
return {
dataList,
videoRef,
likeFun,
collectFun,
handleContainerScroll,
videoRefs,
setVideoRef,
}
},
}
</script>
<style lang="less" scoped>
.cardsVw{
width: 100%;
height: 100%;
// background-color: red;
// overflow: auto;
.scrollView{
width: 100%;
height: 100%;
}
.cardVw{
width: 100%;
min-height: 800rpx;
background-color: white;
border-radius: 20rpx 20rpx 20rpx 20rpx;
margin-bottom: 5%;
box-sizing: border-box;
padding: 3% 3% 2% 3%;
.headerVw{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.avatar {
width: 15%;
image{
width: 80rpx !important;
height: 80rpx !important;
border-radius: 50% !important;
margin-right: 10rpx;
}
}
.nameTime{
width: 85%;
.name{
color: black;
font-size: 30rpx;
font-weight: 600;
}
.time{
color: #606266;
font-size: 20rpx
}
}
}
.textVw{
width: 100%;
// height: 30%;
// background-color: beige;
font-weight: 500;
color: #424249;
margin-bottom: 30rpx;
}
.videoVw{
width: 100%;
margin-bottom: 15rpx;
video{
width: 100%;
height: 400rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx ;
}
}
.likeVw{
display: flex;
justify-content: space-between;
margin-bottom: 15rpx;
.btnVw{
// flex: 1;
display:flex;
align-items: center;
image{
width: 35rpx !important;
height: 35rpx !important;
margin-right: 10rpx;
}
}
}
}
}
</style>
修改我的代码
最新发布