Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
cb2cf54d
提交
cb2cf54d
authored
3月 09, 2023
作者:
方治民
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 新增 ThumbnailPreview 组件,用于预览图片 + 视频
上级
5ad81c48
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
161 行增加
和
0 行删除
+161
-0
index.vue
src/components/ThumbnailPreview/index.vue
+144
-0
utils.ts
src/components/ThumbnailPreview/utils.ts
+17
-0
没有找到文件。
src/components/ThumbnailPreview/index.vue
0 → 100644
浏览文件 @
cb2cf54d
<
script
lang=
"ts"
setup
>
import
type
{
PropType
}
from
'vue'
import
{
nanoid
}
from
'nanoid'
import
{
isImage
,
isVideo
,
getPoster
}
from
'./utils'
type
URLs
=
{
url
:
string
}[]
const
props
=
defineProps
({
width
:
{
type
:
[
String
,
Number
],
default
:
'96'
,
},
height
:
{
type
:
[
String
,
Number
],
default
:
'96'
,
},
mode
:
{
type
:
String
,
default
:
'aspectFit'
,
},
assets
:
{
type
:
Array
as
PropType
<
Recordable
&
URLs
>
,
},
})
// 生成预览容器高度
const
containerHeight
=
`
${
props
.
height
}
rpx`
// 分离图片和视频资源地址
const
images
=
computed
(()
=>
props
.
assets
.
filter
((
item
)
=>
isImage
(
item
.
url
)))
const
videos
=
computed
(()
=>
props
.
assets
.
filter
((
item
)
=>
isVideo
(
item
.
url
)))
// 预览图片
const
preview
=
(
index
:
number
)
=>
{
uni
.
previewImage
({
urls
:
images
.
value
.
map
((
item
)
=>
item
.
url
),
current
:
index
,
})
}
// 初始化视频组件配置
const
videoId
=
nanoid
()
const
videoContext
=
ref
()
const
playVideoSrc
=
ref
()
// 播放视频
const
play
=
(
index
:
number
)
=>
{
playVideoSrc
.
value
=
videos
.
value
[
index
].
url
videoContext
.
value
?.
requestFullScreen
()
videoContext
.
value
?.
play
()
}
const
videoFullScreenChange
=
(
e
:
any
)
=>
{
// 非全屏状态下停止播放
if
(
!
e
.
detail
.
fullScreen
)
{
videoContext
.
value
?.
stop
()
}
}
onMounted
(()
=>
{
// 初始化视频组件上下文对象
videoContext
.
value
=
uni
.
createVideoContext
(
videoId
)
})
</
script
>
<
template
>
<view
class=
"preview-wrap"
>
<!-- 视频预览 -->
<fui-lazyload
class=
"preview-video"
:mode=
"props.mode"
v-for=
"(item, index) in videos"
:key=
"item.url"
:src=
"getPoster(item.url)"
:width=
"props.width"
:height=
"props.height"
:radius=
"10"
@
tap=
"play(index)"
>
<view
class=
"icon-wrap"
:style=
"
{ width: props.width, height: props.height }">
<fui-icon
class=
"video-play-icon"
name=
"suspend"
size=
"40"
color=
"#fff"
/>
</view>
</fui-lazyload>
<!-- 图片预览 -->
<fui-lazyload
class=
"preview-image"
:mode=
"props.mode"
v-for=
"(item, index) in images"
:key=
"item.url"
:src=
"getPoster(item.url)"
:width=
"props.width"
:height=
"props.height"
:radius=
"10"
@
tap=
"preview(index)"
/>
<!-- 视频 -->
<video
:id=
"videoId"
:src=
"playVideoSrc"
class=
"video"
autoplay
controls
@
fullscreenchange=
"videoFullScreenChange"
></video>
</view>
</
template
>
<
style
lang=
"less"
scoped
>
.preview-wrap
{
display
:
flex
;
flex-wrap
:
wrap
;
margin
:
-10
rpx
;
.preview-image,
.preview-video
{
margin
:
10
rpx
!important
;
position
:
relative
;
:deep(.fui-lazyload__img)
{
height
:
v-bind
(
containerHeight
)
!important
;
}
.icon-wrap
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
height
:
100%
;
background-color
:
rgba
(
0
,
0
,
0
,
0.5
);
border-radius
:
10
rpx
;
.video-play-icon
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
}
}
}
.video
{
position
:
absolute
;
top
:
-999999px
;
}
}
</
style
>
src/components/ThumbnailPreview/utils.ts
0 → 100644
浏览文件 @
cb2cf54d
export
type
FileType
=
'image'
|
'video'
|
'audio'
export
function
isImage
(
url
:
string
)
{
return
/
\.(
png|jpe
?
g|gif|svg
)(\?
.*
)?
$/i
.
test
(
url
)
}
export
function
isVideo
(
url
:
string
)
{
return
/
\.(
mp4|m3u8
)(\?
.*
)?
$/i
.
test
(
url
)
}
export
function
getPoster
(
url
:
string
)
{
if
(
!
isVideo
(
url
))
{
return
url
}
return
url
+
'.jpg'
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论