编辑器外观调整,添加全屏按钮

This commit is contained in:
fofolee 2024-12-19 12:57:04 +08:00
parent 45780a2e0c
commit b00048e5ec
4 changed files with 225 additions and 43 deletions

View File

@ -1,5 +1,5 @@
<template>
<div class="absolute-full container" style="overflow: 'hidden'">
<div class="absolute-full container" style="overflow: hidden">
<!-- 命令设置栏 -->
<CommandSideBar
ref="sidebar"
@ -9,17 +9,21 @@
:style="{
width: sideBarWidth + 'px',
zIndex: 1,
// transition: '0.3s',
transform: isFullscreen ? 'translateX(-100%)' : 'translateX(0)',
transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
}"
v-if="showSidebar"
></CommandSideBar>
<!-- 编程语言栏 -->
<div
class="absolute-top"
:style="{
left: showSidebar ? sideBarWidth + 'px' : 65,
zIndex: 1,
// transition: '0.3s',
transform: isFullscreen ? 'translateY(-100%)' : 'translateY(0)',
opacity: isFullscreen ? 0 : 1,
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
}"
>
<div class="row" v-show="!!languageBarHeight">
@ -198,19 +202,40 @@
</q-dialog>
</div>
</div>
<!-- 编辑器 -->
<MonacoEditor
class="absolute-bottom"
class="editor-transition"
:placeholder="true"
ref="editor"
@loaded="monacoInit"
@typing="(val) => monacoTyping(val)"
@keyStroke="monacoKeyStroke"
:style="{
top: languageBarHeight + 'px',
left: action.type === 'run' ? 0 : sideBarWidth + 'px',
// transition: '0.3s',
position: 'absolute',
top: isFullscreen ? 0 : languageBarHeight + 'px',
left: isFullscreen
? 0
: action.type === 'run'
? 0
: sideBarWidth + 'px',
right: 0,
bottom: 0,
}"
/>
<!-- 添加全屏按钮 -->
<q-btn
class="fullscreen-btn"
round
flat
:icon="isFullscreen ? 'fullscreen_exit' : 'fullscreen'"
@click="toggleFullscreen"
>
<q-tooltip>{{
isFullscreen ? "退出全屏 (F11)" : "全屏编辑 (F11)"
}}</q-tooltip>
</q-btn>
<!-- 运行结果 -->
<CommandRunResult :action="action" ref="result"></CommandRunResult>
</div>
@ -264,6 +289,7 @@ export default {
showSidebar: this.action.type !== "run",
isRunCodePage: this.action.type === "run",
listener: null,
isFullscreen: false,
};
},
props: {
@ -298,7 +324,7 @@ export default {
: this.action.data;
quickCommandInfo?.program &&
Object.assign(this.quickcommandInfo, _.cloneDeep(quickCommandInfo));
//
// <EFBFBD><EFBFBD>
if (this.quickcommandInfo.tags?.includes("默认") && !utools.isDev()) {
this.canCommandSave = false;
}
@ -340,7 +366,7 @@ export default {
showHelp() {
window.showUb.docs();
},
//
//
toggleSideBarWidth() {
this.sideBarWidth = !!this.sideBarWidth ? 0 : defaultSideBarWidth;
},
@ -398,10 +424,32 @@ export default {
if (this.quickcommandInfo.program !== "quickcommand") return;
this.runCurrentCommand(`console.log(${data})`);
break;
case "fullscreen":
this.toggleFullscreen();
break;
default:
break;
}
},
getFullscreenScale() {
const currentWidth = window.innerWidth - this.sideBarWidth;
const currentHeight = window.innerHeight - this.languageBarHeight;
const fullWidth = window.innerWidth;
const fullHeight = window.innerHeight;
const scaleX = fullWidth / currentWidth;
const scaleY = fullHeight / currentHeight;
return Math.max(scaleX, scaleY);
},
toggleFullscreen() {
this.isFullscreen = !this.isFullscreen;
//
setTimeout(() => {
this.$refs.editor.resizeEditor();
}, 300);
},
},
};
</script>
@ -415,4 +463,63 @@ export default {
.body--dark .menuBtn {
background: rgba(255, 255, 255, 0.07);
}
.fullscreen-btn {
position: fixed;
right: 20px;
bottom: 20px;
z-index: 1000;
background: rgba(var(--q-primary-rgb), 0.1);
color: var(--q-primary);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.fullscreen-btn:hover {
background: rgba(var(--q-primary-rgb), 0.2);
transform: scale(1.1);
}
.body--dark .fullscreen-btn {
background: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.9);
}
.body--dark .fullscreen-btn:hover {
background: rgba(255, 255, 255, 0.15);
}
/* 统一过渡效果 */
.sidebar-transition,
.language-bar-transition,
.editor-transition {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform, left, top, opacity;
}
.editor-container {
position: relative;
overflow: hidden;
}
.editor-wrapper {
position: absolute;
right: 0;
bottom: 0;
height: auto;
}
.monaco-editor {
width: 100%;
height: 100%;
}
.editor-fullscreen {
left: 0 !important;
top: 0 !important;
z-index: 2;
}
.editor-transition {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
</style>

View File

@ -6,6 +6,7 @@
:horizontal-thumb-style="{
height: '5px',
}"
class="command-side-bar"
>
<div class="row q-pa-md q-gutter-md">
<q-btn
@ -23,7 +24,7 @@
/>
</q-avatar>
<div class="row">
<div>
<div class="command-side-bar-content">
<!-- 说明 -->
<q-input
:disable="!canCommandSave"
@ -37,7 +38,10 @@
label="说明"
>
<template v-slot:prepend>
<q-icon color="primary" name="drive_file_rename_outline" />
<q-icon
class="command-side-bar-icon"
name="drive_file_rename_outline"
/>
</template>
</q-input>
<!-- 匹配类型 -->
@ -63,7 +67,7 @@
label="匹配类型"
>
<template v-slot:prepend>
<q-icon color="primary" :name="cmdType.icon" />
<q-icon class="command-side-bar-icon" :name="cmdType.icon" />
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
@ -102,7 +106,7 @@
@blur="(e) => autoAddInputVal(e, $refs.cmdMatchRef)"
>
<template v-slot:prepend>
<q-icon color="primary" name="square_foot" />
<q-icon class="command-side-bar-icon" name="square_foot" />
</template>
</q-select>
<q-input
@ -119,7 +123,7 @@
:label="cmdType.matchLabel"
>
<template v-slot:prepend>
<q-icon color="primary" name="square_foot" />
<q-icon class="command-side-bar-icon" name="square_foot" />
</template>
</q-input>
<!-- 标签 -->
@ -148,7 +152,7 @@
@blur="(e) => autoAddInputVal(e, $refs.commandTagRef)"
>
<template v-slot:prepend>
<q-icon color="primary" name="label" />
<q-icon class="command-side-bar-icon" name="label" />
</template>
</q-select>
<!-- 特殊变量 -->
@ -174,7 +178,7 @@
label="特殊变量"
>
<template v-slot:prepend>
<q-icon color="primary" name="attach_money" />
<q-icon class="command-side-bar-icon" name="attach_money" />
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
@ -206,7 +210,7 @@
>
<template v-slot:prepend>
<q-icon
color="primary"
class="command-side-bar-icon"
:name="outputTypes[currentCommand.output].icon"
/>
</template>
@ -249,7 +253,7 @@
</div>
</template>
<template v-slot:prepend>
<q-icon color="primary" name="search" />
<q-icon class="command-side-bar-icon" name="search" />
</template>
<template v-slot:append>
<q-toggle
@ -278,7 +282,7 @@
label="平台"
>
<template v-slot:prepend>
<q-icon color="primary" name="window" />
<q-icon class="command-side-bar-icon" name="window" />
</template>
<template v-slot:selected-item="scope">
<q-chip
@ -517,3 +521,61 @@ export default {
},
};
</script>
<style scoped>
.command-side-bar {
height: 100%;
background: #f4f4f4;
}
.body--dark .command-side-bar {
background: #303133;
}
.commandLogo {
cursor: pointer;
transition: 0.2s;
filter: drop-shadow(2px 1px 1px grey);
}
.commandLogo:hover {
transition: 0.5s;
transform: translateY(-1px);
filter: drop-shadow(2px 1px 5px grey);
}
/* 输入框图标基础样式 */
.command-side-bar-icon {
background: var(--q-primary);
border-radius: 8px;
padding: 4px;
color: #f4f4f4;
font-size: 16px;
/* 分开设置不同属性的过渡效果 */
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
backface-visibility: hidden;
transform-style: preserve-3d;
will-change: transform;
-webkit-font-smoothing: subpixel-antialiased;
/* 添加初始transform状态 */
transform: translateZ(0);
}
/* 输入框容器悬浮效果 */
.q-field:hover .command-side-bar-icon {
transform: scale(1.05) translateY(-1px) translateZ(0);
box-shadow: 0 2px 8px rgba(var(--q-primary-rgb), 0.25);
background: var(--q-primary);
opacity: 0.9;
/* 移除font-size变化 */
}
/* 输入框获得焦点时的图标效果 */
.q-field--focused .command-side-bar-icon {
transform: scale(1.1) translateY(-1px) translateZ(0);
box-shadow: 0 3px 12px rgba(var(--q-primary-rgb), 0.3);
background: var(--q-primary);
opacity: 0.85;
}
</style>

View File

@ -1,11 +1,12 @@
<template>
<div>
<div id="monacoEditor" style="width: 100%; height: 100%"></div>
<div class="monaco-container">
<div id="monacoEditor" class="monaco-editor-instance"></div>
<div class="absolute-center flex" v-show="!value && placeholder">
<div class="placeholder text-center q-gutter-md">
<div v-for="shortCut in shortCuts" :key="shortCut">
<span>{{ shortCut[0] }}</span><span class="shortcut-key">{{ shortCut[1] }}</span><span class="shortcut-key">{{
shortCut[2] }}</span>
<span>{{ shortCut[0] }}</span
><span class="shortcut-key">{{ shortCut[1] }}</span
><span class="shortcut-key">{{ shortCut[2] }}</span>
</div>
</div>
</div>
@ -48,7 +49,7 @@ export default {
mounted() {
this.initEditor();
// MonacoResizeObserver loop limit exceeded
window.addEventListener('resize', this.resizeEditor);
window.addEventListener("resize", this.resizeEditor);
this.$emit("loaded");
},
props: {
@ -58,8 +59,7 @@ export default {
initEditor() {
let monacoEditorPreferences = {
value: "",
//
automaticLayout: false,
automaticLayout: true,
foldingStrategy: "indentation",
autoClosingBrackets: true,
tabSize: 2,
@ -78,7 +78,12 @@ export default {
this.bindKeys();
},
resizeEditor() {
this.rawEditor().layout();
if (this.resizeTimeout) {
clearTimeout(this.resizeTimeout);
}
this.resizeTimeout = setTimeout(() => {
this.rawEditor().layout();
}, 50);
},
loadTypes() {
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
@ -115,7 +120,7 @@ export default {
let keys = [];
// fix getValue of undefined
let tokens = getTokens(toRaw(editor).getModel()?.getValue());
//
//
for (const item of tokens) {
if (item != curWord.word) {
keys.push({
@ -127,7 +132,7 @@ export default {
});
}
}
//
// <EFBFBD><EFBFBD>
Object.keys(keyWords).forEach((ItemKind) => {
keyWords[ItemKind].forEach((item) => {
keys.push({
@ -168,7 +173,7 @@ export default {
};
},
});
monacoCompletionProviders[language] = true
monacoCompletionProviders[language] = true;
});
},
setEditorTheme() {
@ -245,6 +250,13 @@ export default {
that.$emit("keyStroke", "log", that.getSelectionOrLineContent());
}
);
// F11
this.rawEditor().addCommand(
monaco.KeyCode.F11,
() => {
this.$emit("keyStroke", "fullscreen");
}
);
},
getSelectionOrLineContent() {
let selection = this.rawEditor().getSelection();
@ -265,13 +277,26 @@ export default {
},
},
beforeUnmount() {
window.removeEventListener('resize', this.resizeEditor);
window.removeEventListener("resize", this.resizeEditor);
this.rawEditor().dispose();
},
};
</script>
<style scoped>
.monaco-container {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.monaco-editor-instance {
width: 100%;
height: 100%;
}
.placeholder {
font-size: 14px;
font-family: sans-serif;

View File

@ -62,18 +62,6 @@ body {
background: #676666;
}
.commandLogo {
cursor: pointer;
transition: 0.2s;
filter: drop-shadow(2px 1px 1px grey);
}
.commandLogo:hover {
transition: 0.5s;
transform: translateY(-5px);
filter: drop-shadow(2px 1px 5px grey);
}
::-webkit-scrollbar {
width: 6px;
height: 6px;