Skip to content

Commit 5fb638c

Browse files
committed
通用组件重构,颜色选择器
1 parent c674ae5 commit 5fb638c

File tree

13 files changed

+253
-34
lines changed

13 files changed

+253
-34
lines changed

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"sober": "^1.1.1",
2323
"utf8": "^3.0.0",
2424
"vue": "^3.5.13",
25+
"vue-color-kit": "^1.0.6",
2526
"vue-draggable-plus": "^0.6.0",
2627
"vue-i18n": "^10.0.7"
2728
},

src/editor/inputs/implicit.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { toRef } from "vue";
2525
import { useI18n } from "vue-i18n";
2626
const { t } = useI18n();
2727
28-
import FilledTextfield from "@/ui/components/filled-textfield.vue";
28+
import FilledTextfield from "@/editor/inputs/subblocks/function.vue";
2929
3030
const props = defineProps<{
3131
folded: boolean;

src/editor/inputs/inputs.scss

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,41 @@
2828
margin: var(--input-inner-gap) 15px;
2929
padding: var(--input-inner-gap) 0;
3030
}
31+
3132
.input-inner-optional {
3233
font-size: 16px;
34+
padding: 0 15px;
3335
.fields {
3436
display: grid;
3537
grid-template-columns: max-content minmax(auto, 15em);
3638
justify-content: space-between;
3739
align-items: center;
38-
padding: 0 15px;
3940
gap: var(--input-inner-gap);
40-
s-text-field {
41-
width: 100%;
42-
font-size: inherit;
43-
&.styled {
44-
font-size: 1.1em;
45-
}
46-
}
47-
.label {
48-
justify-self: start;
49-
}
50-
.input {
51-
justify-self: end;
41+
}
42+
s-text-field {
43+
width: 100%;
44+
font-size: inherit;
45+
&.styled {
46+
font-size: 1.1em;
5247
}
5348
}
49+
.label {
50+
justify-self: start;
51+
display: flex;
52+
}
53+
.input {
54+
justify-self: end;
55+
}
56+
5457
.switches {
5558
display: flex;
56-
padding: 0 15px 0 5px;
5759
margin-top: var(--input-inner-gap);
5860
column-gap: 2em;
5961
align-items: center;
6062
flex-wrap: wrap;
61-
.help {
62-
width: 1.2em;
63-
color: inherit;
64-
margin-left: 0.3em;
65-
}
63+
}
64+
s-checkbox {
65+
margin-left: -10px;
6666
}
6767
}
6868
}

src/editor/inputs/linear.vue

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
<s-divider>{{ t("title.moreOptions") }}</s-divider>
99
<div class="input-inner-optional">
1010
<div class="fields">
11-
<span class="label">颜色</span>
12-
<s-text-field
13-
class="input monospace"
14-
label="颜色"
15-
v-model="self.color"
16-
></s-text-field>
11+
<span class="label">
12+
颜色 <HelpIcon> 鼠标经过时标出的点及其坐标 </HelpIcon>
13+
</span>
14+
<ColorPicker v-model="self.color" />
1715
<span class="label">采样数</span>
1816
<s-text-field
1917
class="input monospace"
@@ -30,10 +28,7 @@
3028
</s-checkbox>
3129
<s-checkbox type="checkbox" v-model.lazy="self.skipTip">
3230
不显示指示条
33-
<s-tooltip>
34-
<s-icon class="help" name="search" slot="trigger"></s-icon>
35-
鼠标经过时标出的点及其坐标
36-
</s-tooltip>
31+
<HelpIcon> 鼠标经过时标出的点及其坐标 </HelpIcon>
3732
</s-checkbox>
3833
</div>
3934
</div>
@@ -54,6 +49,8 @@ const props = defineProps<{
5449
}>();
5550
const self = toRef(props, "self");
5651
57-
import FilledTextfield from "@/ui/components/filled-textfield.vue";
52+
import FilledTextfield from "./subblocks/function.vue";
53+
import HelpIcon from "./subblocks/helpIcon.vue";
54+
import ColorPicker from "./subblocks/colorPicker.vue";
5855
import "./inputs.scss";
5956
</script>

src/editor/inputs/parametric.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { toRef } from "vue";
2525
import { useI18n } from "vue-i18n";
2626
const { t } = useI18n();
2727
28-
import FilledTextfield from "@/ui/components/filled-textfield.vue";
28+
import FilledTextfield from "@/editor/inputs/subblocks/function.vue";
2929
3030
const props = defineProps<{
3131
folded: boolean;

src/editor/inputs/polar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
<script setup lang="ts">
2424
import { PrivateDataTypes } from "@/types/data";
25-
import FilledTextfield from "@/ui/components/filled-textfield.vue";
25+
import FilledTextfield from "@/editor/inputs/subblocks/function.vue";
2626
import { toRef } from "vue";
2727
import { useI18n } from "vue-i18n";
2828
const { t } = useI18n();
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<template>
2+
<s-text-field class="input monospace" label="颜色" v-model="color">
3+
<s-popup slot="end" align="right">
4+
<s-icon-button
5+
slot="trigger"
6+
class="colorpicker-button"
7+
:style="{ color }"
8+
>
9+
<SIconPalette />
10+
</s-icon-button>
11+
<ColorPicker :color="color" sucker-hide @changeColor="changeColor" />
12+
</s-popup>
13+
</s-text-field>
14+
</template>
15+
16+
<script lang="ts" setup>
17+
import SIconPalette from "@/ui/icons/palette.vue";
18+
import { ColorPicker } from "vue-color-kit";
19+
20+
const color = defineModel<string>({ required: true });
21+
22+
interface ColorPickerArgs {
23+
rgba: { r: number; g: number; b: number; a: number };
24+
hex: string;
25+
hsv: { h: number; s: number; v: number };
26+
}
27+
28+
function changeColor(newColor: ColorPickerArgs) {
29+
let { hex } = newColor;
30+
if (newColor.rgba.a < 1) {
31+
hex =
32+
hex +
33+
Math.round(newColor.rgba.a * 255)
34+
.toString(16)
35+
.toUpperCase()
36+
.padStart(2, "0");
37+
}
38+
color.value = hex;
39+
}
40+
</script>
41+
42+
<style lang="scss">
43+
.colorpicker-button {
44+
margin-right: 4px;
45+
margin-left: calc(
46+
var(--text-field-border-radius) - var(--text-field-padding-right) + 4px
47+
);
48+
}
49+
50+
.hu-color-picker {
51+
padding: 15px;
52+
display: flex;
53+
flex-direction: column;
54+
gap: 8px;
55+
--border-radius: 3px;
56+
font-family: var(--font-base);
57+
canvas {
58+
vertical-align: top;
59+
border-radius: var(--border-radius);
60+
}
61+
.color-set {
62+
display: flex;
63+
justify-content: space-between;
64+
}
65+
.color-show {
66+
display: flex;
67+
}
68+
69+
.saturation {
70+
position: relative;
71+
.slide {
72+
position: absolute;
73+
left: 100px;
74+
top: 0;
75+
width: 10px;
76+
height: 10px;
77+
border-radius: 50%;
78+
border: 1px solid #fff;
79+
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.3);
80+
pointer-events: none;
81+
}
82+
}
83+
84+
.color-type {
85+
display: flex;
86+
font-size: 12px;
87+
.name {
88+
width: 60px;
89+
height: 30px;
90+
display: flex;
91+
justify-content: center;
92+
align-items: center;
93+
color: var(--s-color-on-surface-variant);
94+
background: var(--s-color-surface-container-highest);
95+
border-top-left-radius: var(--border-radius);
96+
border-bottom-left-radius: var(--border-radius);
97+
}
98+
.value {
99+
flex: 1;
100+
height: 30px;
101+
min-width: 100px;
102+
padding: 0 12px;
103+
border: 0;
104+
color: var(--s-color-on-surface);
105+
background: var(--s-color-surface-container-high);
106+
box-sizing: border-box;
107+
caret-color: var(--s-color-primary);
108+
border-top-right-radius: var(--border-radius);
109+
border-bottom-right-radius: var(--border-radius);
110+
transition: box-shadow 0.2s;
111+
&:focus {
112+
box-shadow: 0 0 0 1.5px var(--s-color-primary) inset;
113+
}
114+
}
115+
}
116+
117+
.color-alpha,
118+
.hue {
119+
position: relative;
120+
.slide {
121+
position: absolute;
122+
left: 0;
123+
top: 100px;
124+
width: 100%;
125+
height: 4px;
126+
background: #fff;
127+
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.3);
128+
pointer-events: none;
129+
}
130+
}
131+
132+
.colors {
133+
padding: 0;
134+
margin: 0;
135+
display: flex;
136+
flex-wrap: wrap;
137+
gap: 10px;
138+
margin-top: 5px;
139+
.item {
140+
position: relative;
141+
width: 16px;
142+
height: 16px;
143+
border-radius: 3px;
144+
box-sizing: border-box;
145+
vertical-align: top;
146+
display: inline-block;
147+
transition: all 0.1s;
148+
cursor: pointer;
149+
150+
&:hover {
151+
transform: scale(1.2);
152+
}
153+
.alpha {
154+
height: 100%;
155+
border-radius: 4px;
156+
}
157+
.color {
158+
position: absolute;
159+
left: 0;
160+
top: 0;
161+
width: 100%;
162+
height: 100%;
163+
border-radius: 3px;
164+
}
165+
}
166+
}
167+
}
168+
</style>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template>
2+
<s-tooltip>
3+
<SIconInfo class="help" slot="trigger" />
4+
<slot></slot>
5+
</s-tooltip>
6+
</template>
7+
8+
<script setup lang="ts">
9+
import SIconInfo from "@/ui/icons/info.vue";
10+
</script>
11+
12+
<style scoped lang="scss">
13+
.help {
14+
width: 1.2em;
15+
color: inherit;
16+
margin-left: 0.3em;
17+
cursor: help;
18+
opacity: 0.6;
19+
transition: opacity 0.2s;
20+
21+
&:hover {
22+
opacity: 1;
23+
}
24+
}
25+
</style>

0 commit comments

Comments
 (0)