write(ui): input-bar 高度也可拖拽(横向 splitter,row-resize 光标,60-window-200 px)
deploy write / build-and-deploy (push) Successful in 1m28s
deploy write / build-and-deploy (push) Successful in 1m28s
This commit is contained in:
@@ -16,33 +16,39 @@ const recording = ref(false)
|
|||||||
|
|
||||||
onMounted(() => applyLayoutVars())
|
onMounted(() => applyLayoutVars())
|
||||||
|
|
||||||
// ====== 拖拽布局:sidebar 宽(px) + editor/preview 比例(0-1)======
|
// ====== 拖拽布局 ======
|
||||||
|
// sidebarW: 侧栏宽(px) | editorRatio: 源码/预览比例(0-1) | inputH: 输入框高(px)
|
||||||
const sidebarW = ref(parseInt(localStorage.getItem('write.sidebarW') || '260'))
|
const sidebarW = ref(parseInt(localStorage.getItem('write.sidebarW') || '260'))
|
||||||
const editorRatio = ref(parseFloat(localStorage.getItem('write.editorRatio') || '0.5'))
|
const editorRatio = ref(parseFloat(localStorage.getItem('write.editorRatio') || '0.5'))
|
||||||
|
const inputH = ref(parseInt(localStorage.getItem('write.inputH') || '140'))
|
||||||
|
|
||||||
function applyLayoutVars(): void {
|
function applyLayoutVars(): void {
|
||||||
const r = document.documentElement
|
const r = document.documentElement
|
||||||
r.style.setProperty('--sidebar-w', sidebarW.value + 'px')
|
r.style.setProperty('--sidebar-w', sidebarW.value + 'px')
|
||||||
r.style.setProperty('--editor-fr', editorRatio.value + 'fr')
|
r.style.setProperty('--editor-fr', editorRatio.value + 'fr')
|
||||||
r.style.setProperty('--preview-fr', (1 - editorRatio.value) + 'fr')
|
r.style.setProperty('--preview-fr', (1 - editorRatio.value) + 'fr')
|
||||||
|
r.style.setProperty('--input-h', inputH.value + 'px')
|
||||||
}
|
}
|
||||||
|
|
||||||
let dragKind: 'sidebar' | 'editor' | null = null
|
type DragKind = 'sidebar' | 'editor' | 'input'
|
||||||
let dragStartX = 0
|
let dragKind: DragKind | null = null
|
||||||
|
let dragStartPos = 0
|
||||||
let dragStartVal = 0
|
let dragStartVal = 0
|
||||||
let dragPaneW = 0
|
let dragPaneW = 0
|
||||||
|
|
||||||
function startDrag(e: MouseEvent, kind: 'sidebar' | 'editor'): void {
|
function startDrag(e: MouseEvent, kind: DragKind): void {
|
||||||
dragKind = kind
|
dragKind = kind
|
||||||
dragStartX = e.clientX
|
dragStartPos = kind === 'input' ? e.clientY : e.clientX
|
||||||
if (kind === 'sidebar') {
|
if (kind === 'sidebar') {
|
||||||
dragStartVal = sidebarW.value
|
dragStartVal = sidebarW.value
|
||||||
} else {
|
} else if (kind === 'editor') {
|
||||||
dragStartVal = editorRatio.value
|
dragStartVal = editorRatio.value
|
||||||
const pane = (e.currentTarget as HTMLElement).parentElement
|
const pane = (e.currentTarget as HTMLElement).parentElement
|
||||||
dragPaneW = pane ? pane.offsetWidth : window.innerWidth
|
dragPaneW = pane ? pane.offsetWidth : window.innerWidth
|
||||||
|
} else {
|
||||||
|
dragStartVal = inputH.value
|
||||||
}
|
}
|
||||||
document.body.style.cursor = 'col-resize'
|
document.body.style.cursor = kind === 'input' ? 'row-resize' : 'col-resize'
|
||||||
document.body.style.userSelect = 'none'
|
document.body.style.userSelect = 'none'
|
||||||
window.addEventListener('mousemove', onDrag)
|
window.addEventListener('mousemove', onDrag)
|
||||||
window.addEventListener('mouseup', endDrag)
|
window.addEventListener('mouseup', endDrag)
|
||||||
@@ -50,19 +56,25 @@ function startDrag(e: MouseEvent, kind: 'sidebar' | 'editor'): void {
|
|||||||
}
|
}
|
||||||
function onDrag(e: MouseEvent): void {
|
function onDrag(e: MouseEvent): void {
|
||||||
if (!dragKind) return
|
if (!dragKind) return
|
||||||
const dx = e.clientX - dragStartX
|
if (dragKind === 'input') {
|
||||||
|
const dy = dragStartPos - e.clientY // 向上拖 = 高度变大
|
||||||
|
inputH.value = Math.max(60, Math.min(window.innerHeight - 200, dragStartVal + dy))
|
||||||
|
} else {
|
||||||
|
const dx = e.clientX - dragStartPos
|
||||||
if (dragKind === 'sidebar') {
|
if (dragKind === 'sidebar') {
|
||||||
sidebarW.value = Math.max(180, Math.min(500, dragStartVal + dx))
|
sidebarW.value = Math.max(180, Math.min(500, dragStartVal + dx))
|
||||||
} else {
|
} else {
|
||||||
const newR = dragStartVal + dx / Math.max(1, dragPaneW)
|
const newR = dragStartVal + dx / Math.max(1, dragPaneW)
|
||||||
editorRatio.value = Math.max(0.15, Math.min(0.85, newR))
|
editorRatio.value = Math.max(0.15, Math.min(0.85, newR))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
applyLayoutVars()
|
applyLayoutVars()
|
||||||
}
|
}
|
||||||
function endDrag(): void {
|
function endDrag(): void {
|
||||||
if (!dragKind) return
|
if (!dragKind) return
|
||||||
localStorage.setItem('write.sidebarW', String(sidebarW.value))
|
localStorage.setItem('write.sidebarW', String(sidebarW.value))
|
||||||
localStorage.setItem('write.editorRatio', String(editorRatio.value))
|
localStorage.setItem('write.editorRatio', String(editorRatio.value))
|
||||||
|
localStorage.setItem('write.inputH', String(inputH.value))
|
||||||
dragKind = null
|
dragKind = null
|
||||||
document.body.style.cursor = ''
|
document.body.style.cursor = ''
|
||||||
document.body.style.userSelect = ''
|
document.body.style.userSelect = ''
|
||||||
@@ -318,6 +330,8 @@ onMounted(() => {
|
|||||||
<div class="preview" v-html="renderedPreview"></div>
|
<div class="preview" v-html="renderedPreview"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="splitter splitter-input" @mousedown="startDrag($event, 'input')" title="拖动调整输入框高度"></div>
|
||||||
|
|
||||||
<div class="input-bar">
|
<div class="input-bar">
|
||||||
<div class="input-row">
|
<div class="input-row">
|
||||||
<textarea
|
<textarea
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ textarea, input { font: inherit; }
|
|||||||
|
|
||||||
.workspace {
|
.workspace {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 1fr auto;
|
grid-template-rows: 1fr 6px var(--input-h, 140px);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
background: #fafafa;
|
background: #fafafa;
|
||||||
@@ -108,6 +108,9 @@ textarea, input { font: inherit; }
|
|||||||
.splitter:hover { background: #b0c5ff; }
|
.splitter:hover { background: #b0c5ff; }
|
||||||
.splitter-main { /* sidebar | workspace */ }
|
.splitter-main { /* sidebar | workspace */ }
|
||||||
.splitter-editor { /* editor | preview */ }
|
.splitter-editor { /* editor | preview */ }
|
||||||
|
.splitter-input { /* editor-pane | input-bar 横向分隔 */
|
||||||
|
cursor: row-resize;
|
||||||
|
}
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.splitter { display: none; }
|
.splitter { display: none; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user