Skip to content

Commit 18fed75

Browse files
committed
拖拽调整侧边栏宽度
1 parent 9a857ec commit 18fed75

File tree

5 files changed

+109
-65
lines changed

5 files changed

+109
-65
lines changed

src/App.vue

Lines changed: 76 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
<template>
22
<Navbar />
3-
<div id="content">
4-
<div id="editor">
3+
<div id="content" :class="{ onresize: onResize }">
4+
<div id="editor" :style="{ width: sideRatio + 'vw' }">
55
<div class="editor-inner">
6-
<DataBlock
7-
v-for="(_dataItem, i) in graphData"
8-
v-model="graphData[i]"
9-
@delete="graphData.splice(i, 1)"
10-
/>
11-
<div class="plot-data add-data" @click="graphData.push({})">+ 添加</div>
6+
<VueDraggable v-model="graphData" :animation="150" handle=".datablock-drag">
7+
<DataBlock
8+
v-for="(dataItem, i) in graphData"
9+
v-model="graphData[i]"
10+
@delete="graphData.splice(i, 1)"
11+
:key="dataItem.key"
12+
/>
13+
</VueDraggable>
14+
<div
15+
class="plot-data add-data"
16+
@click="graphData.push({ key: Math.random() })"
17+
>
18+
+ 添加
19+
</div>
1220
</div>
1321
<CodeDisplay :dataArr="cloneDeep(graphData)" />
1422
</div>
15-
<Graph :key="graphKey" :graphData="cloneDeep(graphData)" ref="graphRef" />
23+
<div id="divider" @mousedown="handleDrag"></div>
24+
<div id="graph" ref="shellRef">
25+
<Graph
26+
:graphData="cloneDeep(graphData)"
27+
:width="graphWidth"
28+
:height="graphHeight"
29+
/>
30+
</div>
1631
</div>
1732
</template>
1833

@@ -21,13 +36,40 @@ import Navbar from "./components/nav.vue";
2136
import Graph from "./components/graph.vue";
2237
import DataBlock from "./components/dataBlock.vue";
2338
import CodeDisplay from "./components/codeDisplay.vue";
39+
import { VueDraggable } from "vue-draggable-plus";
2440
import type { FunctionPlotDatum } from "function-plot";
25-
import { reactive, ref } from "vue";
41+
import { onMounted, ref } from "vue";
2642
import { cloneDeep } from "lodash-es";
27-
28-
const graphRef = ref<InstanceType<typeof Graph>>();
29-
const graphData = reactive<FunctionPlotDatum[]>([{ fn: "x^2" }]);
30-
const graphKey = ref(0);
43+
const graphData = ref<(FunctionPlotDatum & { key: number })[]>([
44+
{ fn: "x^2", key: 1 },
45+
]);
46+
const graphWidth = ref(0),
47+
graphHeight = ref(0);
48+
const sideRatio = ref(33);
49+
const onResize = ref(false);
50+
const shellRef = ref<HTMLDivElement>();
51+
function handleResize() {
52+
if (shellRef.value) {
53+
graphWidth.value = shellRef.value.clientWidth;
54+
graphHeight.value = shellRef.value.clientHeight;
55+
}
56+
}
57+
onMounted(() => {
58+
window.addEventListener("resize", handleResize);
59+
handleResize();
60+
});
61+
function handleDrag() {
62+
onResize.value = true;
63+
const xfull = outerWidth;
64+
const mousemove = (event: MouseEvent) =>
65+
(sideRatio.value = (event.clientX / xfull) * 100);
66+
document.addEventListener("mousemove", mousemove);
67+
document.addEventListener("mouseup", () => {
68+
document.removeEventListener("mousemove", mousemove);
69+
onResize.value = false;
70+
handleResize();
71+
});
72+
}
3173
</script>
3274

3375
<style>
@@ -59,7 +101,6 @@ const graphKey = ref(0);
59101
flex-shrink: 0;
60102
}
61103
#editor {
62-
width: 33vw;
63104
border-right: var(--c-border) 1px solid;
64105
position: relative;
65106
}
@@ -74,6 +115,7 @@ const graphKey = ref(0);
74115
#graph {
75116
flex-grow: 1;
76117
position: relative;
118+
overflow: hidden;
77119
}
78120
.add-data {
79121
padding-top: 10px;
@@ -87,30 +129,26 @@ const graphKey = ref(0);
87129
.add-data:active {
88130
background: var(--c-bk1);
89131
}
90-
.plot-data.output {
91-
position: absolute;
92-
left: 0;
93-
right: 0;
94-
bottom: 0;
95-
border-top: var(--c-border) 1px solid;
96-
padding: 20px 15px;
97-
height: 260px;
132+
133+
#divider {
134+
width: 6px;
135+
background: var(--c-accent);
136+
margin-left: -3px;
137+
margin-right: -3px;
138+
z-index: 999;
139+
opacity: 0;
140+
transition: opacity 0.1s;
141+
cursor: w-resize;
98142
}
99-
.plot-data.output .output-title {
100-
font-size: 20px;
101-
font-weight: bold;
102-
display: block;
103-
margin-bottom: 10px;
143+
#divider:hover {
144+
opacity: 0.8;
104145
}
105-
.plot-data.output pre {
106-
position: absolute;
107-
top: 60px;
108-
bottom: 15px;
109-
left: 15px;
110-
right: 15px;
111-
margin: 0;
112-
overflow: scroll;
113-
user-select: all;
146+
.onresize #divider {
147+
opacity: 0.3;
148+
transition: none;
149+
}
150+
.onresize {
151+
cursor: w-resize;
152+
user-select: none;
114153
}
115-
116154
</style>

src/components/codeDisplay.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@ import prettierPluginBabel from "prettier/plugins/babel";
1212
import prettierPluginEstree from "prettier/plugins/estree";
1313
import { FunctionPlotDatum } from "function-plot";
1414
import { ref, watch } from "vue";
15-
const { dataArr } = defineProps<{ dataArr: FunctionPlotDatum[] }>();
15+
const { dataArr } = defineProps<{
16+
dataArr: (FunctionPlotDatum & { key?: number })[];
17+
}>();
1618
const formatted = ref("");
1719
watch(
1820
() => dataArr,
1921
() => {
2022
dataArr.forEach((item) => {
2123
if (item.graphType === "text") delete item.fnType;
24+
delete item.key;
2225
});
2326
prettier
2427
.format(JSON5.stringify({ data: dataArr }), {

src/components/dataBlockInner/strInputs.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { FunctionPlotDatum } from "function-plot";
1515
const { dataItem, fnType } = defineProps<{
1616
dataItem: FunctionPlotDatum;
1717
fnType: FnType;
18+
blockFolded: boolean;
1819
}>();
1920
</script>
2021

src/components/graph.vue

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,40 @@
11
<template>
2-
<div id="graph" ref="shellRef">
3-
<div id="graphRender" ref="plotRef"></div>
4-
</div>
2+
<div id="graphRender" ref="plotRef"></div>
53
</template>
64

75
<script setup lang="ts">
8-
import { onMounted, onUnmounted, ref, watch } from "vue";
6+
import { onMounted, ref, watch } from "vue";
97
import { throttle } from "lodash-es";
108
import type { FunctionPlotDatum } from "function-plot";
119
import { findError } from "../consts";
12-
const { graphData } = defineProps<{ graphData: FunctionPlotDatum[] }>();
10+
const { graphData, width, height } = defineProps<{
11+
graphData: FunctionPlotDatum[];
12+
width: number;
13+
height: number;
14+
}>();
1315
14-
const shellRef = ref<HTMLDivElement | null>(null);
1516
const plotRef = ref<HTMLDivElement | null>(null);
16-
const width = ref(0),
17-
height = ref(0);
18-
const handleResize = () => {
19-
if (shellRef.value) {
20-
width.value = shellRef.value.clientWidth;
21-
height.value = shellRef.value.clientHeight;
22-
}
23-
};
2417
onMounted(async () => {
2518
const functionPlot = (await import("function-plot")).default;
26-
handleResize();
27-
window.addEventListener("resize", handleResize);
2819
watch(
29-
[width, height, graphData],
20+
[() => width, () => height, () => graphData],
3021
throttle(() => {
3122
const flag = findError(graphData);
32-
if (plotRef.value)
33-
try {
23+
try {
24+
plotRef.value &&
3425
functionPlot({
3526
target: plotRef.value,
3627
data: flag ? graphData.slice(0, flag) : graphData,
37-
width: width.value - 20,
38-
height: height.value - 20,
28+
width: width - 20,
29+
height: height - 20,
3930
});
40-
} catch (e) {
41-
console.log(e);
42-
}
31+
} catch (e) {
32+
console.log(e);
33+
}
4334
}, 200),
4435
{ immediate: true }
4536
);
4637
});
47-
onUnmounted(() => window.removeEventListener("resize", handleResize));
4838
</script>
4939

5040
<style>
@@ -54,11 +44,21 @@ onUnmounted(() => window.removeEventListener("resize", handleResize));
5444
right: 0;
5545
left: 0;
5646
bottom: 0;
47+
width: fit-content;
48+
height: fit-content;
49+
margin: auto;
5750
filter: invert(100%) hue-rotate(180deg) brightness(133%);
5851
color: black;
5952
user-select: none;
6053
}
54+
55+
.onresize #graphRender {
56+
left: 50%;
57+
right: unset;
58+
width: fit-content;
59+
transform: translateX(-50%);
60+
}
6161
.top-right-legend {
62-
transform: translateY(20px);
62+
display: none;
6363
}
6464
</style>

src/style.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
text-rendering: optimizeLegibility;
2020
-webkit-font-smoothing: antialiased;
2121
-moz-osx-font-smoothing: grayscale;
22+
cursor: default;
23+
user-select: none;
2224
}
2325

2426
:root,

0 commit comments

Comments
 (0)