优化时间线组件
- 更新时间轴操作说明 - 解决播放头在移动时的粗细变化 - 解决快速拖动播放头,松开鼠标后的播放头闪现
This commit is contained in:
parent
e26be2cb89
commit
8cd8045649
|
|
@ -98,9 +98,19 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 2px;
|
width: 2px;
|
||||||
background-color: #ef4444;
|
|
||||||
z-index: 25;
|
z-index: 25;
|
||||||
cursor: ew-resize;
|
cursor: ew-resize;
|
||||||
|
transform: translateZ(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.playhead::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 2px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #ef4444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playhead-indicator {
|
.playhead-indicator {
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ export function useTimeline(
|
||||||
const isPlayheadDragging = ref(false)
|
const isPlayheadDragging = ref(false)
|
||||||
const isRulerDragging = ref(false)
|
const isRulerDragging = ref(false)
|
||||||
const isMounted = ref(false)
|
const isMounted = ref(false)
|
||||||
|
const displayFrame = ref(0)
|
||||||
const dragStartX = ref(0)
|
const dragStartX = ref(0)
|
||||||
const scrollStartLeft = ref(0)
|
const scrollStartLeft = ref(0)
|
||||||
const localCurrentFrame = ref(0)
|
const localCurrentFrame = ref(0)
|
||||||
|
|
@ -121,18 +122,16 @@ export function useTimeline(
|
||||||
// 计算缩放前后的位置偏移
|
// 计算缩放前后的位置偏移
|
||||||
// console.log('container.scrollLeft', container.scrollLeft)
|
// console.log('container.scrollLeft', container.scrollLeft)
|
||||||
if (playheadVisible) {
|
if (playheadVisible) {
|
||||||
// 以播放头为中心缩放
|
|
||||||
const playheadX = playheadPosition - containerScrollLeft
|
const playheadX = playheadPosition - containerScrollLeft
|
||||||
const newPlayheadPosition = props.currentFrame * newPxPerFrame
|
const newPlayheadPosition = props.currentFrame * newPxPerFrame
|
||||||
const newScrollLeft = newPlayheadPosition - playheadX
|
const newScrollLeft = Math.round(newPlayheadPosition - playheadX)
|
||||||
container.scrollLeft = newScrollLeft
|
container.scrollLeft = newScrollLeft
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// 以容器中心为中心缩放
|
|
||||||
const centerX = containerWidth / 2
|
const centerX = containerWidth / 2
|
||||||
const centerPosition = containerScrollLeft + centerX
|
const centerPosition = containerScrollLeft + centerX
|
||||||
const newCenterPosition = centerPosition * (newPxPerFrame / oldPxPerFrame)
|
const newCenterPosition = centerPosition * (newPxPerFrame / oldPxPerFrame)
|
||||||
container.scrollLeft = newCenterPosition - centerX
|
container.scrollLeft = Math.round(newCenterPosition - centerX)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最后更新缩放值
|
// 最后更新缩放值
|
||||||
|
|
@ -175,9 +174,7 @@ export function useTimeline(
|
||||||
}
|
}
|
||||||
|
|
||||||
const playheadPos: ComputedRef<number> = computed(() => {
|
const playheadPos: ComputedRef<number> = computed(() => {
|
||||||
const frame = isPlayheadDragging.value ? localCurrentFrame.value : props.currentFrame
|
return Math.round(displayFrame.value * pxPerFrame.value)
|
||||||
const clampedFrame = Math.max(0, Math.min(frame, props.totalFrames - 1))
|
|
||||||
return clampedFrame * pxPerFrame.value
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const trackRows: ComputedRef<HazardRow[][]> = computed(() => {
|
const trackRows: ComputedRef<HazardRow[][]> = computed(() => {
|
||||||
|
|
@ -260,6 +257,15 @@ export function useTimeline(
|
||||||
if (!timelineContainer.value)
|
if (!timelineContainer.value)
|
||||||
return
|
return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
|
if (e.shiftKey) {
|
||||||
|
const delta = e.deltaY || e.deltaX
|
||||||
|
const zoomDelta = delta > 0 ? -0.1 : 0.1
|
||||||
|
const newZoom = pxPerFrame.value + zoomDelta
|
||||||
|
setZoom(newZoom)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const container = timelineContainer.value
|
const container = timelineContainer.value
|
||||||
const delta = e.deltaY || e.deltaX
|
const delta = e.deltaY || e.deltaX
|
||||||
container.scrollLeft += delta
|
container.scrollLeft += delta
|
||||||
|
|
@ -318,6 +324,7 @@ export function useTimeline(
|
||||||
const frame = Math.floor(x / pxPerFrame.value)
|
const frame = Math.floor(x / pxPerFrame.value)
|
||||||
const clampedFrame = Math.max(0, Math.min(frame, props.totalFrames - 1))
|
const clampedFrame = Math.max(0, Math.min(frame, props.totalFrames - 1))
|
||||||
localCurrentFrame.value = clampedFrame
|
localCurrentFrame.value = clampedFrame
|
||||||
|
displayFrame.value = clampedFrame
|
||||||
emit('frameChange', clampedFrame)
|
emit('frameChange', clampedFrame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -330,13 +337,16 @@ export function useTimeline(
|
||||||
const frame = Math.floor(x / pxPerFrame.value)
|
const frame = Math.floor(x / pxPerFrame.value)
|
||||||
const clampedFrame = Math.max(0, Math.min(frame, props.totalFrames - 1))
|
const clampedFrame = Math.max(0, Math.min(frame, props.totalFrames - 1))
|
||||||
localCurrentFrame.value = clampedFrame
|
localCurrentFrame.value = clampedFrame
|
||||||
|
displayFrame.value = clampedFrame
|
||||||
emit('frameChange', clampedFrame)
|
emit('frameChange', clampedFrame)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.currentFrame, () => {
|
watch(() => props.currentFrame, () => {
|
||||||
if (!isPlayheadDragging.value) {
|
if (isPlayheadDragging.value)
|
||||||
localCurrentFrame.value = props.currentFrame
|
return
|
||||||
}
|
|
||||||
|
displayFrame.value = props.currentFrame
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (!timelineContainer.value)
|
if (!timelineContainer.value)
|
||||||
return
|
return
|
||||||
|
|
@ -408,7 +418,7 @@ export function useTimeline(
|
||||||
isDragging,
|
isDragging,
|
||||||
isPlayheadDragging,
|
isPlayheadDragging,
|
||||||
isRulerDragging,
|
isRulerDragging,
|
||||||
localCurrentFrame,
|
displayFrame,
|
||||||
trackWidth,
|
trackWidth,
|
||||||
timeTicks,
|
timeTicks,
|
||||||
secondTicks,
|
secondTicks,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ onUnmounted(() => {
|
||||||
<el-button
|
<el-button
|
||||||
type="info" dashed :icon="InfoFilled" size="small"
|
type="info" dashed :icon="InfoFilled" size="small"
|
||||||
@click="openMessageBox(
|
@click="openMessageBox(
|
||||||
'拖动播放头控制播放进度。滚轮/拖动时间轴前后移动。点击隐患编号跳转对应隐患。',
|
'拖动播放头 控制播放进度。滚轮/拖动 时间轴前后移动。点击隐患编号跳转对应隐患。shift键+鼠标滚轮 缩放时间轴。',
|
||||||
'操作说明',
|
'操作说明',
|
||||||
)"
|
)"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue