HarmonyOS鸿蒙Next中如何做到video组件src更新的时候给视频加个过渡效果
HarmonyOS鸿蒙Next中如何做到video组件src更新的时候给视频加个过渡效果
Video({ src: CommonConstants.videoList[this.currentIndex].src, controller: CommonConstants.videoList[this.currentIndex].controller, }).width(‘100%’).height(‘100%’)
我是 通过改变 this.currentIndex 来实现切换全屏视频的
试了好几种方法都不行 请问如何才能 在 video 组件 src 更新的时候给视频加个过渡效果(在视频加载之前
更多关于HarmonyOS鸿蒙Next中如何做到video组件src更新的时候给视频加个过渡效果的实战教程也可以访问 https://www.itying.com/category-93-b0.html
您好,可以使用淡入淡出达成过渡效果。
参考代码如下:
@Entry
@Component
struct VideoTransition {
[@State](/user/State) currentSrc: Resource = $r('app.media.video1');
[@State](/user/State) opacityValue: number = 1;
controller: VideoController = new VideoController();
build() {
Column() {
Video({
src: this.currentSrc,
previewUri: $r('app.media.preview'), // 必须设置预览图
controller: this.controller
})
.opacity(this.opacityValue)
.onPrepared(() => { // 视频加载完成回调
animateTo({ duration: 500 }, () => {
this.opacityValue = 1; // 淡入新视频
});
})
}
}
// 视频切换方法
changeVideo(newSrc: Resource) {
animateTo({ duration: 300 }, () => {
this.opacityValue = 0; // 先淡出当前视频
}).then(() => {
this.currentSrc = newSrc; // 更新视频源
this.controller.start(); // 自动播放新视频
});
}
}
- 通过previewUri设置预览图,避免切换时黑屏
- 使用animateTo实现透明度动画过渡
- 在onPrepared回调中触发动画,确保视频加载完成
- 通过@State变量驱动UI更新
更多关于HarmonyOS鸿蒙Next中如何做到video组件src更新的时候给视频加个过渡效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
// xxx.ets
@Component struct VideoCreateComponent { @State videoSrc: Resource = $r(‘app.media.uav’); @State previewUri: Resource = $r(‘app.media.uav’); @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X; @State isAutoPlay: boolean = false; @State showControls: boolean = true; @State isShortcutKeyEnabled: boolean = false; @State scaleX: number = 1; @State scaleY: number = 1; @State opacityValue: number = 1; controller: VideoController = new VideoController();
build() { Column() { Column() { Video({ src: this.videoSrc, previewUri: this.previewUri, currentProgressRate: this.curRate, controller: this.controller }) .width(‘100%’) .height(600) .scale({ x: this.scaleX, y: this.scaleY }) .autoPlay(this.isAutoPlay) .controls(this.showControls) .enableShortcutKey(this.isShortcutKeyEnabled) .opacity(this.opacityValue) .onStart(() => { console.info(‘onStart’) }) .onPause(() => { console.info(‘onPause’) }) .onFinish(() => { console.info(‘onFinish’) }) .onError(() => { console.info(‘onError’) }) .onStop(() => { console.info(‘onStop’) }) .onPrepared((e?: DurationObject) => { if (e != undefined) { console.info('onPrepared is ’ + e.duration) } this.controller.setCurrentTime(0) this.controller.start() setTimeout(() => { this.controller.stop() }, 50) }) .onSeeking((e?: TimeObject) => { if (e != undefined) { console.info('onSeeking is ’ + e.time) } }) .onSeeked((e?: TimeObject) => { if (e != undefined) { console.info('onSeeked is ’ + e.time) } }) .onUpdate((e?: TimeObject) => { if (e != undefined) { console.info('onUpdate is ’ + e.time) } }) .onFullscreenChange((e?: FullscreenObject) => { if (e != undefined) { console.info('onFullscreenChange is ’ + e.fullscreen) } }) }.width(‘100%’) .backgroundColor(Color.Black)
Row() {
Button('scale过渡').onClick(() => {
animateTo({
duration: 500,
onFinish: () => {
// 切换视频源
animateTo({
duration: 500,
}, () => {
if (this.videoSrc.id == $r('app.media.hdc').id) {
this.videoSrc = $r('app.media.uav')
} else {
this.videoSrc = $r('app.media.hdc')
}
this.scaleX = 1;
this.scaleY = 1;
});
}
}, () => {
this.scaleX = 0;
this.scaleY = 0;
});
}).margin(5)
Button('显隐过渡').onClick(() => {
animateTo({
duration: 500,
onFinish: () => {
// 切换视频源
animateTo({
duration: 500,
}, () => {
if (this.videoSrc.id == $r('app.media.hdc').id) {
this.videoSrc = $r('app.media.uav')
} else {
this.videoSrc = $r('app.media.hdc')
}
this.opacityValue = 1;
});
}
}, () => {
this.opacityValue = 0;
});
}).margin(5)
}
}
} }
interface DurationObject { duration: number; }
interface TimeObject { time: number; }
interface FullscreenObject { fullscreen: boolean; }
核心思路
- 分离视频状态:将视频的显示 / 隐藏状态与
currentIndex
解耦,使用独立状态(如showVideo
)控制过渡动画。 - 使用
Animate
组件:包裹视频容器,在状态变化时触发进入 / 退出动画(如渐变、缩放等)。 - 延迟加载新视频:在旧视频退出动画完成后,再更新
src
并显示新视频,确保过渡效果完整。
兄弟哪里来的 Animate 组件呀,arkts 没有这个组件吧,
在HarmonyOS Next中,可以通过VideoController和自定义动画实现Video组件src更新时的过渡效果。首先创建VideoController实例绑定到Video组件。在更新src前,使用ArkUI的动画API(如animateTo)执行淡出动画,设置opacity从1到0。然后更新src属性,再执行淡入动画,opacity从0到1。关键代码示例:
@State opacity: number = 1;
videoController: VideoController = new VideoController();
changeSrc() {
animateTo({ duration: 300 }, () => {
this.opacity = 0;
});
// 更新src后
animateTo({ duration: 300 }, () => {
this.opacity = 1;
});
}
Video组件需设置opacity属性绑定状态变量。
在HarmonyOS Next中,可以通过结合动画组件和状态管理来实现视频切换时的过渡效果。以下是实现方案:
- 使用Stack布局叠加Video和动画组件:
@State currentIndex: number = 0;
@State showVideo: boolean = true;
build() {
Stack() {
if (showVideo) {
Video({
src: CommonConstants.videoList[currentIndex].src,
controller: CommonConstants.videoList[currentIndex].controller,
})
.width('100%')
.height('100%')
.onReady(() => {
// 视频加载完成后淡入
animateTo({ duration: 300 }, () => {
opacityValue = 1;
});
})
.opacity(opacityValue)
}
// 过渡动画层
if (isChanging) {
Image($r('app.media.transition_image')) // 可以是纯色或特效图片
.width('100%')
.height('100%')
.transition(TransitionEffect.OPACITY.animation({ duration: 300 }))
}
}
}
- 切换视频时触发过渡动画:
changeVideo(index: number) {
// 先显示过渡层
isChanging = true;
opacityValue = 0;
// 延迟执行视频切换
setTimeout(() => {
currentIndex = index;
isChanging = false;
}, 300); // 与动画持续时间保持一致
}
关键点:
- 使用opacity属性控制淡入淡出效果
- 通过setTimeout确保动画执行完成后再切换视频源
- 可以配合transition或animateTo实现更复杂的动画效果
注意:由于Video组件本身的限制,过渡效果主要依靠外层容器的动画来实现。