当前位置:网站首页>18_ The wechat video number of wechat applet scrolls and automatically plays the video effect to achieve 2.0
18_ The wechat video number of wechat applet scrolls and automatically plays the video effect to achieve 2.0
2022-07-03 01:03:00 【andr_ gale】
18_ The wechat video number of wechat applet scrolls and automatically plays the video effect 2.0
One . First on the renderings
About this effect , I have implemented one before 12_ The wechat video number of wechat applet scrolls and automatically plays the video effect , But the previous implementation is monitoring scroll-view Of onscroll, according to scroll-view The sliding position of is dynamically calculated to play index To control automatic playback , This article will use the wechat applet to provide us IntersectionObserver To achieve .
Two .IntersectionObserver
IntersectionObserver wx.createIntersectionObserver(Object component, Object options)
- Used on the page : IntersectionObserver wx.createIntersectionObserver(this, {observeAll: true}),observeAll by true It can listen to multiple nodes at the same time
- Use... In custom components :IntersectionObserver this.createIntersectionObserver({observeAll: true})
IntersectionObserver IntersectionObserver.relativeTo(string selector, Object margins)
- Use the selector to specify a node , As a reference area
IntersectionObserver.observe(string targetSelector, IntersectionObserver.observeCallback callback)
- Specify the selector of the target node and listen by relativeTo Whether the specified reference area intersects with the target node , Because we need to monitor multiple video node , So here we use the target node selector class A selector is enough .
- When the target node intersects with the reference area ,callback(res) Back to res Medium intersectionRatio Greater than 0
- When the target node does not intersect the reference area ,callback(res) Back to res Medium intersectionRatio be equal to 0
IntersectionObserver.disconnect()
Finally, when the page or component is destroyed , Need to call IntersectionObserver.disconnect() Cancel monitoring
When used in a page , stay onUnload Method can be called
When used in components , stay detached Method can be called
3、 ... and . Video list rendering
For details, please refer to 12_ The wechat video number of wechat applet scrolls and automatically plays the video effect , Here is the code directly .
<scroll-view class="video-list" scroll-y>
<view class="list">
<view class="video-item-wrapper video" style="width: {
{
item.videoWidth}}px;" wx:for="{
{_videoList}}">
<view class="video-item" style="height: {
{
item.videoHeight}}px;">
<video wx:if="{
{playIndex == index}}" id="player" class="player" src="{
{item.src}}" object-fit="contain" show-center-play-btn="{
{false}}" custom-cache="{
{true}}" autoplay="{
{true}}"></video>
<block wx:else>
<image class="thumbnail" src="{
{
'data:image/jpg;base64,' + item.thumbnail}}"/>
<view class="action">
<view class="play-wrapper" bindtap="play" data-index="{
{index}}">
<image class="play" src="./images/ic_play.png"/>
<view style="margin-top: 10rpx;">{
{item.formatDur}}</view>
</view>
</view>
</block>
</view>
</view>
<view style="width: 100%; height: {
{
_videoList[0] ? _videoList[0].videoHeight + 'px' : '600rpx'}};"></view>
</view>
</scroll-view>
.video-list {
width: 100%;
height: 100vh;
}
.list {
width: 100%;
}
.video-item-wrapper {
background: #000;
/* padding-top: 200rpx; padding-bottom: 200rpx; */
margin-top: 20rpx;
}
.video-item-wrapper:last-child {
margin-bottom: 20rpx;
}
.video-item {
position: relative;
width: 100%;
}
.thumbnail, .player {
position: absolute;
left: 50%;
top: 50%;
width: 100%;
height: 100%;
transform: translate(-50%, -50%);
}
.action {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .6);
}
.play-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
}
.play {
width: 48rpx;
height: 48rpx;
}
Component({
/** * A list of properties of a component */
properties: {
videoList: {
type: Array,
value: [],
observer: function(newVal, oldVal) {
var that = this
const query = that.createSelectorQuery()
query.select(".video-list").boundingClientRect()
query.exec((res) => {
var itemWidth = res[0].width
for(var i=0; i<newVal.length; i++) {
newVal[i].videoWidth = Math.floor(itemWidth)
newVal[i].videoHeight = Math.floor(itemWidth/(newVal[i].width/newVal[i].height))
}
that.setData({
_videoList: newVal
})
})
}
},
playIndex: {
type: Number,
value: -1,
observer: function(newVal, oldVal) {
var that = this
this.setData({
playIndex: newVal
})
if(newVal >= 0) {
var videoContext = wx.createVideoContext('player', that)
if(videoContext) {
videoContext.stop()
}
var timer = setTimeout(function() {
clearTimeout(timer)
var videoContext = wx.createVideoContext('player', that)
if(videoContext) {
videoContext.play()
}
}, 500)
}
}
}
},
/** * The initial data of the component */
data: {
_videoList: []
},
/** * A list of methods for a component */
methods: {
play: function(event) {
var that = this
var index = event.currentTarget.dataset.index
this.setData({
playIndex: index
})
}
}
})
Four . Select the reference node
Here we can take the position half the height of the first video as the reference node , In practical application, you can also set reference nodes according to your own needs .
<scroll-view class="video-list" scroll-y>
<view class="list">
<view class="video-item-wrapper video" style="width: {
{
item.videoWidth}}px;" wx:for="{
{_videoList}}">
<view class="video-item" style="height: {
{
item.videoHeight}}px;">
<video wx:if="{
{playIndex == index}}" id="player" class="player" src="{
{item.src}}" object-fit="contain" show-center-play-btn="{
{false}}" custom-cache="{
{true}}" autoplay="{
{true}}"></video>
<block wx:else>
<image class="thumbnail" src="{
{
'data:image/jpg;base64,' + item.thumbnail}}"/>
<view class="action">
<view class="play-wrapper" bindtap="play" data-index="{
{index}}">
<image class="play" src="./images/ic_play.png"/>
<view style="margin-top: 10rpx;">{
{item.formatDur}}</view>
</view>
</view>
</block>
</view>
</view>
<view style="width: 100%; height: {
{
_videoList[0] ? _videoList[0].videoHeight + 'px' : '600rpx'}};"></view>
</view>
</scroll-view>
<view class="relativeView" style="top: {
{
_videoList[0] ? _videoList[0].videoHeight/2 + 'px':'30%'}};"></view>
.relativeView {
position: fixed;
left: 0;
top: 30%;
width: 100%;
height: 1px;
background: #f00;
}
We analyze a wave according to the above picture , By default , The first video intersects with the reference , Control the first video playback , When you slide up to the intersection of the second video and the reference , Control the second video playback
5、 ... and . Slide autoplay
The above analysis has been clear , Go straight to the code .
<scroll-view class="video-list" scroll-y>
<view class="list">
<!-- Appoint data-index="{
{index}}", When the prison heard that there was video When a node intersects a reference node , Can pass index How many video tags intersect the reference node when the current one is obtained -->
<view class="video-item-wrapper video" style="width: {
{
item.videoWidth}}px;" wx:for="{
{_videoList}}" data-index="{
{index}}">
<view class="video-item" style="height: {
{
item.videoHeight}}px;">
<video wx:if="{
{playIndex == index}}" id="player" class="player" src="{
{item.src}}" object-fit="contain" show-center-play-btn="{
{false}}" custom-cache="{
{true}}" autoplay="{
{true}}"></video>
<block wx:else>
<image class="thumbnail" src="{
{
'data:image/jpg;base64,' + item.thumbnail}}"/>
<view class="action">
<view class="play-wrapper" bindtap="play" data-index="{
{index}}">
<image class="play" src="./images/ic_play.png"/>
<view style="margin-top: 10rpx;">{
{item.formatDur}}</view>
</view>
</view>
</block>
</view>
</view>
<view style="width: 100%; height: {
{
_videoList[0] ? _videoList[0].videoHeight + 'px' : '600rpx'}};"></view>
</view>
</scroll-view>
<view class="relativeView" style="top: {
{
_videoList[0] ? _videoList[0].videoHeight/2 + 'px':'30%'}};"></view>
Component({
/** * A list of properties of a component */
properties: {
videoList: {
type: Array,
value: [],
observer: function(newVal, oldVal) {
var that = this
const query = that.createSelectorQuery()
query.select(".video-list").boundingClientRect()
query.exec((res) => {
var itemWidth = res[0].width
for(var i=0; i<newVal.length; i++) {
newVal[i].videoWidth = Math.floor(itemWidth)
newVal[i].videoHeight = Math.floor(itemWidth/(newVal[i].width/newVal[i].height))
}
that.setData({
_videoList: newVal
})
this.intersectionObserver = this.createIntersectionObserver({
observeAll: true})
this.intersectionObserver.relativeTo('.relativeView')
.observe(".video", (res) => {
let index = res.dataset.index
let intersectionRatio = res.intersectionRatio
if(intersectionRatio > 0) {
that.setData({
playIndex: index
})
}
})
})
}
},
...
},
...
})
Be accomplished …
6、 ... and . Hide reference nodes
Be careful : Reference nodes cannot be set here hidden=“{ {true}}” Or use wx:if, otherwise , The intersection between the target node and the reference node will not be monitored , Instead, use z-index.
<view class="relativeView" style="top: {
{
_videoList[0] ? _videoList[0].videoHeight/2 + 'px':'30%'}}; z-index: -9999"></view>
Finally, when the components are destroyed , Just cancel listening
lifetimes: {
detached: function() {
if (this.intersectionObserver) {
this.intersectionObserver.disconnect()
}
}
},
边栏推荐
- [applet project development -- JD mall] user defined search component of uni app (middle) -- search suggestions
- Advanced pointer (I)
- 删除有序链表中重复的元素-II
- 飞凌搭载TI AM62x的ARM核心板/开发板首发上市,亮相Embedded World 2022
- Explain the basic concepts and five attributes of RDD in detail
- RISA rz/g2l processor introduction | frame diagram | power consumption | schematic diagram and hardware design guide
- [overview of AUTOSAR three RTE]
- [AUTOSAR twelve mode management]
- 【AutoSAR 四 BSW概述】
- [shutter] image component (cached_network_image network image caching plug-in)
猜你喜欢
瑞萨RZ/G2L ARM开发板存储读写速度与网络实测
1.11 - bus
AEM: Nanlin fan Ben et al. - plant rhizosphere growth promoting bacteria control soybean blight
[overview of AUTOSAR three RTE]
ROS2之ESP32简单速度消息测试(极限频率)
【AutoSAR 十二 模式管理】
【C语言】分支和循环语句(上)
Leetcode-849: maximum distance to the nearest person
这不平凡的两年,感谢我们一直在一起!
excel表格计算时间日期的差值,并转化为分钟数
随机推荐
【AutoSAR 六 描述文件】
【C语言】分支和循环语句(上)
这不平凡的两年,感谢我们一直在一起!
[AUTOSAR twelve mode management]
[introduction to AUTOSAR seven tool chain]
leetcode:701. 二叉搜索树中的插入操作【bst的插入】
Infrared thermography temperature detection system based on arm rk3568
Solve the cache problem of reactnative using WebView
Vulkan practice first bullet
Vulkan is not a "panacea"“
[AUTOSAR XIII NVM]
2022 list of manufacturers of Chinese 3D vision enterprises (guided positioning and sorting scenes)
无向图的割点
FPGA - 7系列 FPGA内部结构之Clocking -04- 多区域时钟
leetcode-241:为运算表达式设计优先级
Leetcode-934: the shortest Bridge
1.12 - 指令
Win10 多种方式解决无法安装.Net3.5的问题
MySQL multi table joint deletion
Leetcode-871: minimum refueling times