当前位置:网站首页>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()
}
}
},
边栏推荐
- Leetcode-224: basic calculator
- leetcode-224:基本计算器
- (C language) data storage
- 465. DFS backtracking of optimal bill balance
- First hand evaluation of Reza electronics rz/g2l development board
- 【AutoSAR 十一 通信相关机制】
- Illustrated network: what is virtual router redundancy protocol VRRP?
- leetcode-849:到最近的人的最大距离
- Kubernetes resource object introduction and common commands (V) - (NFS & PV & PVC)
- 寻找标杆战友 | 百万级实时数据平台,终身免费使用
猜你喜欢

Lu Zhe, chief scientist of Shiping information: building data and personnel centered security capabilities
【AutoSAR 五 方法论】

指针进阶(一)

Explain the basic concepts and five attributes of RDD in detail

(C language) data storage

1.11 - 总线

【C语言】分支和循环语句(上)

matlab将数字矩阵保存为地理空间数据出错,显示下标索引必须为正整数类型或逻辑类型,解决

Win10 多种方式解决无法安装.Net3.5的问题

Test shift right: Elk practice of online quality monitoring
随机推荐
[AUTOSAR + IO Architecture]
Rk3568 development board evaluation (II): development environment construction
Test shift right: Elk practice of online quality monitoring
Array and collection performance comparison
[shutter] image component (configure local GIF image resources | load placeholder with local resources)
[overview of AUTOSAR three RTE]
leetcode-934:最短的桥
Liad: the consumer end of micro LED products is first targeted at TVs above 100 inches. At this stage, it is still difficult to enter a smaller size
1.12 - Instructions
2022.2.14 resumption
FPGA - 7 Series FPGA internal structure clocking -04- multi area clock
Basic use of sringcloud & use of component Nacos
Rust ownership (very important)
Leetcode-2115: find all the dishes that can be made from the given raw materials
[AUTOSAR 11 communication related mechanism]
1038 Recover the Smallest Number
Advanced pointer (I)
matlab将数字矩阵保存为地理空间数据出错,显示下标索引必须为正整数类型或逻辑类型,解决
Matlab saves the digital matrix as geospatial data, and the display subscript index must be of positive integer type or logical type. Solve the problem
Leetcode-849: maximum distance to the nearest person