✨ Feat: 添加半模态转场
This commit is contained in:
parent
914c1ca917
commit
ae149eef94
|
@ -2,9 +2,10 @@
|
||||||
import { CustomPanel } from '../components/CustomPanel';
|
import { CustomPanel } from '../components/CustomPanel';
|
||||||
import curves from '@ohos.curves';
|
import curves from '@ohos.curves';
|
||||||
import { InnerView } from '../views/InnerView'
|
import { InnerView } from '../views/InnerView'
|
||||||
|
import { SideBar } from '../views/SideBar';
|
||||||
|
|
||||||
// 方案1:panel
|
// 1:custom panel
|
||||||
// 方案2:模态转场
|
// 2:模态转场
|
||||||
@Preview
|
@Preview
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
|
@ -15,12 +16,16 @@ struct Index {
|
||||||
@State showPanel: boolean = false;
|
@State showPanel: boolean = false;
|
||||||
// 模态转场控制变量
|
// 模态转场控制变量
|
||||||
@State isPresent: boolean = false;
|
@State isPresent: boolean = false;
|
||||||
@State contentWidth: number | string = this.defaultWidth;
|
@State sheetIsPresent: boolean = false;
|
||||||
@State marginLeft: number = 0;
|
|
||||||
|
// @State contentWidth: number | string = this.defaultWidth;
|
||||||
|
// @State marginLeft: number = 0;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
innerView() {
|
innerView() {
|
||||||
InnerView();
|
InnerView()
|
||||||
|
.height('100%')
|
||||||
|
.width('100%')
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClose() {
|
handleClose() {
|
||||||
|
@ -28,75 +33,99 @@ struct Index {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sidebar控制变量
|
// sidebar控制变量
|
||||||
controlValue = {
|
// controlValue = {
|
||||||
beginX: 0,
|
// beginX: 0,
|
||||||
endX: 0,
|
// endX: 0,
|
||||||
maxMoveRate: 0.12,
|
// maxMoveRate: 0.12,
|
||||||
swipeDirection: 0, // 0 is left, 1 is right
|
// swipeDirection: 0, // 0 is left, 1 is right
|
||||||
leftMoveDistance: 0,
|
// leftMoveDistance: 0,
|
||||||
}
|
// }
|
||||||
|
// @Builder
|
||||||
|
// sideBar_origin() {
|
||||||
|
// Column() {
|
||||||
|
// InnerView()
|
||||||
|
// }
|
||||||
|
// .margin({ left: -this.marginLeft })
|
||||||
|
// .width(this.contentWidth)
|
||||||
|
// .height('100%')
|
||||||
|
// .transition( // 通过转场动画实现出现消失转场动画效果,transition需要加在builder下的第一个组件
|
||||||
|
// TransitionEffect.translate({ x: '-' + this.contentWidth, y: 0, z: 0 })
|
||||||
|
// .animation({ curve: curves.springMotion(0.6, 0.8) })
|
||||||
|
// )
|
||||||
|
// .onTouch(event => {
|
||||||
|
// // 按下赋初始值
|
||||||
|
// if (event.type === TouchType.Down) {
|
||||||
|
// this.controlValue.beginX = event.touches[0].displayX;
|
||||||
|
// this.controlValue.leftMoveDistance = 0;
|
||||||
|
// }
|
||||||
|
// // 移动改变移动宽度
|
||||||
|
// if (event.type === TouchType.Move) {
|
||||||
|
// this.controlValue.endX = event.touches[0].displayX; // 手指停止的位置
|
||||||
|
// const moveDistance = this.controlValue.beginX - this.controlValue.endX; // 滑动的水平距离
|
||||||
|
//
|
||||||
|
// // 判断水平滑动方向
|
||||||
|
// if (this.controlValue.leftMoveDistance > 0) {
|
||||||
|
// this.controlValue.swipeDirection = 0;
|
||||||
|
// } else {
|
||||||
|
// this.controlValue.swipeDirection = 1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 更新
|
||||||
|
// this.marginLeft = (this.marginLeft + moveDistance) > 0 ? (this.marginLeft + moveDistance) : 0;
|
||||||
|
//
|
||||||
|
// this.controlValue.beginX = this.controlValue.endX;
|
||||||
|
//
|
||||||
|
// this.controlValue.leftMoveDistance += moveDistance
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (event.type === TouchType.Up) {
|
||||||
|
// console.log(this.TAG, 'TouchType up' + this.controlValue.leftMoveDistance);
|
||||||
|
// if (this.controlValue.leftMoveDistance > this.controlValue.maxMoveRate * +this.defaultWidth) {
|
||||||
|
// this.isPresent = false;
|
||||||
|
// }
|
||||||
|
// this.marginLeft = 0;
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .gesture(
|
||||||
|
// SwipeGesture({ direction: SwipeDirection.Horizontal })
|
||||||
|
// .onAction((event?: GestureEvent) => {
|
||||||
|
// if (event && this.controlValue.swipeDirection == 0) {
|
||||||
|
// this.isPresent = false;
|
||||||
|
// this.marginLeft = 0;
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// ) // 快速滑动关闭
|
||||||
|
// }
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
SideBar() {
|
sideBarComponent() {
|
||||||
InnerView()
|
SideBar({
|
||||||
.margin({ left: -this.marginLeft })
|
contentView: () => this.innerView(),
|
||||||
.width(this.contentWidth)
|
contentWidth: this.defaultWidth,
|
||||||
.height('100%')
|
onClose: () => this.isPresent = false,
|
||||||
|
})
|
||||||
.transition(// 通过转场动画实现出现消失转场动画效果,transition需要加在builder下的第一个组件
|
.transition(// 通过转场动画实现出现消失转场动画效果,transition需要加在builder下的第一个组件
|
||||||
TransitionEffect.translate({ x: '-' + this.contentWidth, y: 0, z: 0 })
|
TransitionEffect.translate({ x: '-' + this.defaultWidth, y: 0, z: 0 })
|
||||||
.animation({ curve: curves.springMotion(0.6, 0.8) })
|
.animation({ curve: curves.springMotion(0.6, 0.8) })
|
||||||
)
|
)
|
||||||
.onTouch(event => {
|
|
||||||
// 按下赋初始值
|
|
||||||
if (event.type === TouchType.Down) {
|
|
||||||
this.controlValue.beginX = event.touches[0].displayX;
|
|
||||||
this.controlValue.leftMoveDistance = 0;
|
|
||||||
}
|
|
||||||
// 移动改变移动宽度
|
|
||||||
if (event.type === TouchType.Move) {
|
|
||||||
this.controlValue.endX = event.touches[0].displayX; // 手指停止的位置
|
|
||||||
const moveDistance = this.controlValue.beginX - this.controlValue.endX; // 滑动的水平距离
|
|
||||||
|
|
||||||
// 判断水平滑动方向
|
|
||||||
if (this.controlValue.leftMoveDistance > 0) {
|
|
||||||
this.controlValue.swipeDirection = 0;
|
|
||||||
} else {
|
|
||||||
this.controlValue.swipeDirection = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新
|
|
||||||
this.marginLeft = (this.marginLeft + moveDistance) > 0 ? (this.marginLeft + moveDistance) : 0;
|
|
||||||
|
|
||||||
this.controlValue.beginX = this.controlValue.endX;
|
|
||||||
|
|
||||||
this.controlValue.leftMoveDistance += moveDistance
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type === TouchType.Up) {
|
|
||||||
console.log(this.TAG, 'TouchType up' + this.controlValue.leftMoveDistance);
|
|
||||||
if (this.controlValue.leftMoveDistance > this.controlValue.maxMoveRate * +this.defaultWidth) {
|
|
||||||
this.isPresent = false;
|
|
||||||
}
|
|
||||||
this.marginLeft = 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.gesture(
|
|
||||||
SwipeGesture({ direction: SwipeDirection.Horizontal })
|
|
||||||
.onAction((event?: GestureEvent) => {
|
|
||||||
if (event && this.controlValue.swipeDirection == 0) {
|
|
||||||
this.isPresent = false;
|
|
||||||
this.marginLeft = 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
) // 快速滑动关闭
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
|
||||||
Row() {
|
Row() {
|
||||||
Button('open panel')
|
// mask
|
||||||
.onClick(() => this.showPanel = true);
|
// if (this.isPresent) {
|
||||||
Button('模态转场')// 通过选定的模态接口,绑定模态展示界面,ModalTransition是内置的ContentCover转场动画类型,这里选择None代表系统不加默认动画
|
// Row()
|
||||||
.bindContentCover(this.isPresent, this.SideBar, ModalTransition.NONE)
|
// .width('100%')
|
||||||
|
// .height('100%')
|
||||||
|
// .position({ x: 0, y: 0 })
|
||||||
|
// .backgroundColor('#80111317')
|
||||||
|
// }
|
||||||
|
|
||||||
|
Button('open panel').onClick(() => this.showPanel = true);
|
||||||
|
|
||||||
|
Button('全屏模态转场')// 通过选定的模态接口,绑定模态展示界面,ModalTransition是内置的ContentCover转场动画类型,这里选择None代表系统不加默认动画
|
||||||
|
.bindContentCover(this.isPresent, this.sideBarComponent, ModalTransition.NONE)
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
if (this.isPresent) {
|
if (this.isPresent) {
|
||||||
this.isPresent = false;
|
this.isPresent = false;
|
||||||
|
@ -104,9 +133,19 @@ struct Index {
|
||||||
} else {
|
} else {
|
||||||
this.isPresent = true;
|
this.isPresent = true;
|
||||||
}
|
}
|
||||||
this.contentWidth = this.defaultWidth;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Button('半模态转场')
|
||||||
|
.onClick(() => {
|
||||||
|
if (this.sheetIsPresent) {
|
||||||
|
this.sheetIsPresent = false;
|
||||||
|
this.sheetIsPresent = true;
|
||||||
|
} else {
|
||||||
|
this.sheetIsPresent = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.bindSheet(this.sheetIsPresent, this.innerView(), { height: 300, dragBar: true })
|
||||||
|
|
||||||
CustomPanel({
|
CustomPanel({
|
||||||
contentView: () => this.innerView(),
|
contentView: () => this.innerView(),
|
||||||
show: this.showPanel,
|
show: this.showPanel,
|
||||||
|
@ -117,6 +156,5 @@ struct Index {
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.justifyContent(FlexAlign.SpaceEvenly)
|
.justifyContent(FlexAlign.SpaceEvenly)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
73
entry/src/main/ets/views/SideBar.ets
Normal file
73
entry/src/main/ets/views/SideBar.ets
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
@Component
|
||||||
|
export struct SideBar {
|
||||||
|
private TAG: string = 'Sidebar';
|
||||||
|
private defaultWidth: number = 350
|
||||||
|
@BuilderParam contentView: () => void
|
||||||
|
// 模态转场控制变量
|
||||||
|
onClose?: () => void
|
||||||
|
@Prop contentWidth: number | string = this.defaultWidth;
|
||||||
|
@State marginLeft: number = 0;
|
||||||
|
// sidebar控制变量
|
||||||
|
controlValue = {
|
||||||
|
beginX: 0,
|
||||||
|
endX: 0,
|
||||||
|
maxMoveRate: 0.12,
|
||||||
|
swipeDirection: 0, // 0 is left, 1 is right
|
||||||
|
leftMoveDistance: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
aboutToDisappear() {
|
||||||
|
this.onClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
Column() {
|
||||||
|
this.contentView()
|
||||||
|
}
|
||||||
|
.margin({ left: -this.marginLeft })
|
||||||
|
.width(this.contentWidth)
|
||||||
|
.height('100%')
|
||||||
|
.onTouch(event => {
|
||||||
|
// 按下赋初始值
|
||||||
|
if (event.type === TouchType.Down) {
|
||||||
|
this.controlValue.beginX = event.touches[0].displayX;
|
||||||
|
this.controlValue.leftMoveDistance = 0;
|
||||||
|
}
|
||||||
|
// 移动改变宽度
|
||||||
|
if (event.type === TouchType.Move) {
|
||||||
|
this.controlValue.endX = event.touches[0].displayX; // 手指停止的位置
|
||||||
|
const moveDistance = this.controlValue.beginX - this.controlValue.endX; // 滑动的水平距离
|
||||||
|
|
||||||
|
// 判断水平滑动方向
|
||||||
|
if (this.controlValue.leftMoveDistance > 0) {
|
||||||
|
this.controlValue.swipeDirection = 0;
|
||||||
|
} else {
|
||||||
|
this.controlValue.swipeDirection = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新
|
||||||
|
this.marginLeft = (this.marginLeft + moveDistance) > 0 ? (this.marginLeft + moveDistance) : 0;
|
||||||
|
this.controlValue.beginX = this.controlValue.endX;
|
||||||
|
this.controlValue.leftMoveDistance += moveDistance
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手指抬起判断是否关闭
|
||||||
|
if (event.type === TouchType.Up) {
|
||||||
|
console.log(this.TAG, 'TouchType up' + this.controlValue.leftMoveDistance);
|
||||||
|
if (this.controlValue.leftMoveDistance > this.controlValue.maxMoveRate * +this.defaultWidth) {
|
||||||
|
this.onClose()
|
||||||
|
}
|
||||||
|
this.marginLeft = 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.gesture(
|
||||||
|
SwipeGesture({ direction: SwipeDirection.Horizontal })
|
||||||
|
.onAction((event?: GestureEvent) => {
|
||||||
|
if (event && this.controlValue.swipeDirection == 0) {
|
||||||
|
this.onClose()
|
||||||
|
this.marginLeft = 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
) // 快速滑动关闭
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user