Skip to content

Commit 76ec681

Browse files
committed
向量面板
1 parent 7459c01 commit 76ec681

File tree

5 files changed

+99
-25
lines changed

5 files changed

+99
-25
lines changed

src/editor/inputs/inputs.scss

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@
2929
padding: var(--input-inner-gap) 0;
3030
}
3131

32+
.fields {
33+
display: grid;
34+
grid-template-columns: max-content minmax(auto, 18em);
35+
justify-content: space-between;
36+
align-items: center;
37+
gap: var(--input-inner-gap);
38+
}
39+
3240
.input-inner-optional {
3341
font-size: 16px;
3442
padding: 0 15px;
35-
.fields {
36-
display: grid;
37-
grid-template-columns: max-content minmax(auto, 18em);
38-
justify-content: space-between;
39-
align-items: center;
40-
gap: var(--input-inner-gap);
41-
}
43+
4244
s-text-field {
4345
width: 100%;
4446
font-size: inherit;
@@ -65,4 +67,16 @@
6567
color: var(--s-color-outline);
6668
}
6769
}
70+
71+
.tuple {
72+
display: flex;
73+
align-items: center;
74+
font-size: 24px;
75+
gap: 0.2em;
76+
}
77+
.tuple-input {
78+
width: 0;
79+
flex-grow: 1;
80+
font-size: 22px;
81+
}
6882
}

src/editor/inputs/vector.vue

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,62 @@
11
<template>
2-
<span class="input-title styled">r=</span>
3-
<s-text-field
4-
class="styled"
5-
ref="inputBox"
6-
label="x"
7-
v-model="self.vector[0]"
8-
></s-text-field>
9-
<s-text-field
10-
class="styled"
11-
ref="inputBox"
12-
label="y"
13-
v-model="self.vector[1]"
14-
></s-text-field>
15-
<s-divider>{{ t("title.moreOptions") }}</s-divider>
2+
<div class="input-inner vector">
3+
<div class="fields">
4+
<span class="input-title">{{ t("data.main.vector") }}</span>
5+
<div class="tuple">
6+
<span class="tuple-label styled">(</span>
7+
<s-text-field
8+
class="styled tuple-input"
9+
label="Δx"
10+
v-model="vectorX"
11+
type="number"
12+
></s-text-field>
13+
<span class="tuple-label styled">,</span>
14+
<s-text-field
15+
class="styled tuple-input"
16+
label="Δy"
17+
v-model="vectorY"
18+
type="number"
19+
></s-text-field>
20+
<span class="tuple-label styled">)</span>
21+
</div>
22+
<span class="input-title">{{ t("data.main.offset") }}</span>
23+
<div class="tuple">
24+
<span class="tuple-label styled">(</span>
25+
<s-text-field
26+
class="styled tuple-input"
27+
label="x₀"
28+
v-model="offsetX"
29+
type="number"
30+
></s-text-field>
31+
<span class="tuple-label styled">,</span>
32+
<s-text-field
33+
class="styled tuple-input"
34+
label="y₀"
35+
v-model="offsetY"
36+
type="number"
37+
></s-text-field>
38+
<span class="tuple-label styled">)</span>
39+
</div>
40+
</div>
41+
<AnimatedFold :folded="props.folded">
42+
<s-divider>{{ t("data.more.dividerTitle") }}</s-divider>
43+
<div class="input-inner-optional">
44+
<div class="fields">
45+
<!-- color -->
46+
<span class="label">
47+
{{ t("data.more.color") }}
48+
<HelpIcon> {{ t("data.more.colorHelp") }} </HelpIcon>
49+
</span>
50+
<ColorPicker v-model="self.color" />
51+
</div>
52+
</div>
53+
</AnimatedFold>
54+
</div>
1655
</template>
1756

1857
<script setup lang="ts">
1958
import { PrivateDataTypes } from "@/types/data";
20-
import { toRef } from "vue";
59+
import { ref, toRef, watch } from "vue";
2160
import { useI18n } from "vue-i18n";
2261
import { I18nSchema } from "@/i18n";
2362
const { t } = useI18n<{ message: I18nSchema }>();
@@ -28,4 +67,18 @@ const props = defineProps<{
2867
index: number;
2968
}>();
3069
const self = toRef(props, "self");
70+
71+
import AnimatedFold from "@/ui/animated/animatedFold.vue";
72+
import HelpIcon from "./subblocks/helpIcon.vue";
73+
import ColorPicker from "./subblocks/colorPicker.vue";
74+
75+
const vectorX = ref<number | "">(self.value.vector[0]);
76+
const vectorY = ref<number | "">(self.value.vector[1]);
77+
const offsetX = ref<number | "">(self.value.offset[0] || "");
78+
const offsetY = ref<number | "">(self.value.offset[1] || "");
79+
80+
watch(vectorX, (val) => (self.value.vector[0] = val || 0));
81+
watch(vectorY, (val) => (self.value.vector[1] = val || 0));
82+
watch(offsetX, (val) => (self.value.offset[0] = val || 0));
83+
watch(offsetY, (val) => (self.value.offset[1] = val || 0));
3184
</script>

src/i18n/en-US.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@
5656
"less": "Less Options"
5757
},
5858
"main": {
59-
"fnType": "Function Type",
60-
"graphType": "Renderer"
59+
"fnType": "Type",
60+
"graphType": "Renderer",
61+
"vector": "Vector Size",
62+
"offset": "Offset",
63+
"text": "Text"
6164
},
6265
"more": {
6366
"dividerTitle": "More Options",

src/i18n/zh-CN.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@
5757
},
5858
"main": {
5959
"fnType": "图形类型",
60-
"graphType": "绘制方式"
60+
"graphType": "绘制方式",
61+
"vector": "向量大小",
62+
"offset": "起点坐标",
63+
"text": "文本"
6164
},
6265
"more": {
6366
"dividerTitle": "更多选项",

src/types/data.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export function toPublicData(data: PrivateData): FunctionPlotDatum {
177177
range: (val) => val === undefined,
178178
derivative: (val) => val === undefined,
179179
secants: (val) => val === undefined,
180+
offset: ([x, y]) => !x && !y,
180181
}
181182
);
182183
}

0 commit comments

Comments
 (0)