mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: drag subtitle
Closes #588 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -949,6 +949,132 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
},
|
||||
flipX: plPlayerController.flipX.value,
|
||||
flipY: plPlayerController.flipY.value,
|
||||
onVerticalDragStart: (details) {
|
||||
if (plPlayerController.controlsLock.value) return;
|
||||
if (details.localPosition.dy < 40) return;
|
||||
if (details.localPosition.dx < 40) return;
|
||||
if (details.localPosition.dx > context.width - 40) return;
|
||||
if (details.localPosition.dy > context.height - 40) return;
|
||||
_initialFocalPoint = details.localPosition;
|
||||
_gestureType = null;
|
||||
},
|
||||
onVerticalDragUpdate: (details) {
|
||||
if (plPlayerController.controlsLock.value) return;
|
||||
if (plPlayerController.enableSlideVolumeBrightness.not &&
|
||||
plPlayerController.enableSlideFS.not) {
|
||||
return;
|
||||
}
|
||||
RenderBox renderBox =
|
||||
_playerKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final double totalWidth = renderBox.size.width;
|
||||
final double tapPosition = details.localPosition.dx;
|
||||
final double sectionWidth = totalWidth / 3;
|
||||
late String gestureType;
|
||||
if (tapPosition < sectionWidth) {
|
||||
if (plPlayerController.enableSlideVolumeBrightness.not) {
|
||||
return;
|
||||
}
|
||||
// 左边区域
|
||||
gestureType = 'left';
|
||||
} else if (tapPosition < sectionWidth * 2) {
|
||||
if (plPlayerController.enableSlideFS.not) {
|
||||
return;
|
||||
}
|
||||
// 全屏
|
||||
gestureType = 'center';
|
||||
} else {
|
||||
if (plPlayerController.enableSlideVolumeBrightness.not) {
|
||||
return;
|
||||
}
|
||||
// 右边区域
|
||||
gestureType = 'right';
|
||||
}
|
||||
|
||||
if (_gestureType != null && _gestureType != gestureType) {
|
||||
return;
|
||||
}
|
||||
_gestureType = gestureType;
|
||||
|
||||
if (_gestureType == 'left') {
|
||||
// 左边区域 👈
|
||||
final double level = renderBox.size.height * 3;
|
||||
final double brightness =
|
||||
_brightnessValue.value - details.delta.dy / level;
|
||||
final double result = brightness.clamp(0.0, 1.0);
|
||||
setBrightness(result);
|
||||
} else if (_gestureType == 'center') {
|
||||
// 全屏
|
||||
const double threshold = 2.5; // 滑动阈值
|
||||
double cumulativeDy =
|
||||
details.localPosition.dy - _initialFocalPoint.dy;
|
||||
|
||||
void fullScreenTrigger(bool status) {
|
||||
plPlayerController.triggerFullScreen(status: status);
|
||||
}
|
||||
|
||||
if (cumulativeDy > threshold) {
|
||||
_gestureType = 'center_down';
|
||||
if (isFullScreen ^ fullScreenGestureReverse) {
|
||||
fullScreenTrigger(fullScreenGestureReverse);
|
||||
}
|
||||
// debugPrint('center_down:$cumulativeDy');
|
||||
} else if (cumulativeDy < -threshold) {
|
||||
_gestureType = 'center_up';
|
||||
if (!isFullScreen ^ fullScreenGestureReverse) {
|
||||
fullScreenTrigger(!fullScreenGestureReverse);
|
||||
}
|
||||
// debugPrint('center_up:$cumulativeDy');
|
||||
}
|
||||
} else if (_gestureType == 'right') {
|
||||
// 右边区域
|
||||
final double level = renderBox.size.height * 0.5;
|
||||
EasyThrottle.throttle(
|
||||
'setVolume', const Duration(milliseconds: 20), () {
|
||||
final double volume =
|
||||
_volumeValue.value - details.delta.dy / level;
|
||||
final double result = volume.clamp(0.0, 1.0);
|
||||
setVolume(result);
|
||||
});
|
||||
}
|
||||
},
|
||||
onVerticalDragEnd: (details) {
|
||||
interacting = false;
|
||||
_initialFocalPoint = Offset.zero;
|
||||
_gestureType = null;
|
||||
},
|
||||
onTap: () {
|
||||
plPlayerController.controls =
|
||||
!plPlayerController.showControls.value;
|
||||
},
|
||||
onDoubleTapDown: (TapDownDetails details) {
|
||||
// live模式下禁用 锁定时🔒禁用
|
||||
if (plPlayerController.videoType.value == 'live' ||
|
||||
plPlayerController.controlsLock.value) {
|
||||
return;
|
||||
}
|
||||
RenderBox renderBox =
|
||||
_playerKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final double totalWidth = renderBox.size.width;
|
||||
final double tapPosition = details.localPosition.dx;
|
||||
final double sectionWidth = totalWidth / 4;
|
||||
String type = 'left';
|
||||
if (tapPosition < sectionWidth) {
|
||||
type = 'left';
|
||||
} else if (tapPosition < sectionWidth * 3) {
|
||||
type = 'center';
|
||||
} else {
|
||||
type = 'right';
|
||||
}
|
||||
doubleTapFuc(type);
|
||||
},
|
||||
onLongPressStart: (LongPressStartDetails detail) {
|
||||
plPlayerController.setLongPressStatus(true);
|
||||
},
|
||||
onLongPressEnd: (LongPressEndDetails details) {
|
||||
plPlayerController.setLongPressStatus(false);
|
||||
},
|
||||
enableDragSubtitle: plPlayerController.enableDragSubtitle,
|
||||
onUpdatePadding: plPlayerController.onUpdatePadding,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1155,143 +1281,6 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
||||
// }
|
||||
// }),
|
||||
|
||||
/// 手势
|
||||
Positioned.fill(
|
||||
left: 16,
|
||||
top: 25,
|
||||
right: 15,
|
||||
bottom: 15,
|
||||
child: Semantics(
|
||||
label: '双击开关控件',
|
||||
child: GestureDetector(
|
||||
onVerticalDragStart: (details) {
|
||||
if (plPlayerController.controlsLock.value) return;
|
||||
if (details.localPosition.dy < 40) return;
|
||||
if (details.localPosition.dx < 40) return;
|
||||
if (details.localPosition.dx > context.width - 40) return;
|
||||
if (details.localPosition.dy > context.height - 40) return;
|
||||
_initialFocalPoint = details.localPosition;
|
||||
_gestureType = null;
|
||||
},
|
||||
onVerticalDragUpdate: (details) {
|
||||
if (plPlayerController.controlsLock.value) return;
|
||||
if (plPlayerController.enableSlideVolumeBrightness.not &&
|
||||
plPlayerController.enableSlideFS.not) {
|
||||
return;
|
||||
}
|
||||
RenderBox renderBox =
|
||||
_playerKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final double totalWidth = renderBox.size.width;
|
||||
final double tapPosition = details.localPosition.dx;
|
||||
final double sectionWidth = totalWidth / 3;
|
||||
late String gestureType;
|
||||
if (tapPosition < sectionWidth) {
|
||||
if (plPlayerController.enableSlideVolumeBrightness.not) {
|
||||
return;
|
||||
}
|
||||
// 左边区域
|
||||
gestureType = 'left';
|
||||
} else if (tapPosition < sectionWidth * 2) {
|
||||
if (plPlayerController.enableSlideFS.not) {
|
||||
return;
|
||||
}
|
||||
// 全屏
|
||||
gestureType = 'center';
|
||||
} else {
|
||||
if (plPlayerController.enableSlideVolumeBrightness.not) {
|
||||
return;
|
||||
}
|
||||
// 右边区域
|
||||
gestureType = 'right';
|
||||
}
|
||||
|
||||
if (_gestureType != null && _gestureType != gestureType) {
|
||||
return;
|
||||
}
|
||||
_gestureType = gestureType;
|
||||
|
||||
if (_gestureType == 'left') {
|
||||
// 左边区域 👈
|
||||
final double level = renderBox.size.height * 3;
|
||||
final double brightness =
|
||||
_brightnessValue.value - details.delta.dy / level;
|
||||
final double result = brightness.clamp(0.0, 1.0);
|
||||
setBrightness(result);
|
||||
} else if (_gestureType == 'center') {
|
||||
// 全屏
|
||||
const double threshold = 2.5; // 滑动阈值
|
||||
double cumulativeDy =
|
||||
details.localPosition.dy - _initialFocalPoint.dy;
|
||||
|
||||
void fullScreenTrigger(bool status) {
|
||||
plPlayerController.triggerFullScreen(status: status);
|
||||
}
|
||||
|
||||
if (cumulativeDy > threshold) {
|
||||
_gestureType = 'center_down';
|
||||
if (isFullScreen ^ fullScreenGestureReverse) {
|
||||
fullScreenTrigger(fullScreenGestureReverse);
|
||||
}
|
||||
// debugPrint('center_down:$cumulativeDy');
|
||||
} else if (cumulativeDy < -threshold) {
|
||||
_gestureType = 'center_up';
|
||||
if (!isFullScreen ^ fullScreenGestureReverse) {
|
||||
fullScreenTrigger(!fullScreenGestureReverse);
|
||||
}
|
||||
// debugPrint('center_up:$cumulativeDy');
|
||||
}
|
||||
} else if (_gestureType == 'right') {
|
||||
// 右边区域
|
||||
final double level = renderBox.size.height * 0.5;
|
||||
EasyThrottle.throttle(
|
||||
'setVolume', const Duration(milliseconds: 20), () {
|
||||
final double volume =
|
||||
_volumeValue.value - details.delta.dy / level;
|
||||
final double result = volume.clamp(0.0, 1.0);
|
||||
setVolume(result);
|
||||
});
|
||||
}
|
||||
},
|
||||
onVerticalDragEnd: (details) {
|
||||
interacting = false;
|
||||
_initialFocalPoint = Offset.zero;
|
||||
_gestureType = null;
|
||||
},
|
||||
onTap: () {
|
||||
plPlayerController.controls =
|
||||
!plPlayerController.showControls.value;
|
||||
},
|
||||
onDoubleTapDown: (TapDownDetails details) {
|
||||
// live模式下禁用 锁定时🔒禁用
|
||||
if (plPlayerController.videoType.value == 'live' ||
|
||||
plPlayerController.controlsLock.value) {
|
||||
return;
|
||||
}
|
||||
RenderBox renderBox =
|
||||
_playerKey.currentContext!.findRenderObject() as RenderBox;
|
||||
final double totalWidth = renderBox.size.width;
|
||||
final double tapPosition = details.localPosition.dx;
|
||||
final double sectionWidth = totalWidth / 4;
|
||||
String type = 'left';
|
||||
if (tapPosition < sectionWidth) {
|
||||
type = 'left';
|
||||
} else if (tapPosition < sectionWidth * 3) {
|
||||
type = 'center';
|
||||
} else {
|
||||
type = 'right';
|
||||
}
|
||||
doubleTapFuc(type);
|
||||
},
|
||||
onLongPressStart: (LongPressStartDetails detail) {
|
||||
plPlayerController.setLongPressStatus(true);
|
||||
},
|
||||
onLongPressEnd: (LongPressEndDetails details) {
|
||||
plPlayerController.setLongPressStatus(false);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// 头部、底部控制条
|
||||
Obx(
|
||||
() => Positioned.fill(
|
||||
|
||||
Reference in New Issue
Block a user