Browse Source

字体、选择颜色、层级、尺寸、图标

qianduan 8 months ago
parent
commit
b414178b8d

+ 95 - 0
package-lock.json

@@ -9,6 +9,7 @@
       "version": "0.0.0",
       "dependencies": {
         "@element-plus/icons-vue": "^2.3.1",
+        "color": "^4.2.3",
         "element-plus": "^2.7.5",
         "vue": "^3.4.21",
         "vue-drag-resize": "^1.5.4",
@@ -1019,6 +1020,43 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/color": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz",
+      "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+      "dependencies": {
+        "color-convert": "^2.0.1",
+        "color-string": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=12.5.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "node_modules/color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "dependencies": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
     "node_modules/computeds": {
       "version": "0.0.1",
       "resolved": "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz",
@@ -1178,6 +1216,11 @@
       "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==",
       "dev": true
     },
+    "node_modules/is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+    },
     "node_modules/is-binary-path": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -1477,6 +1520,14 @@
         "node": ">=10"
       }
     },
+    "node_modules/simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "dependencies": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
     "node_modules/sortablejs": {
       "version": "1.14.0",
       "resolved": "https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz",
@@ -2271,6 +2322,37 @@
         "readdirp": "~3.6.0"
       }
     },
+    "color": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz",
+      "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+      "requires": {
+        "color-convert": "^2.0.1",
+        "color-string": "^1.9.0"
+      }
+    },
+    "color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "requires": {
+        "color-name": "~1.1.4"
+      }
+    },
+    "color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "color-string": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz",
+      "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+      "requires": {
+        "color-name": "^1.0.0",
+        "simple-swizzle": "^0.2.2"
+      }
+    },
     "computeds": {
       "version": "0.0.1",
       "resolved": "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz",
@@ -2398,6 +2480,11 @@
       "integrity": "sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==",
       "dev": true
     },
+    "is-arrayish": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz",
+      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+    },
     "is-binary-path": {
       "version": "2.1.0",
       "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -2582,6 +2669,14 @@
       "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
       "dev": true
     },
+    "simple-swizzle": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+      "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+      "requires": {
+        "is-arrayish": "^0.3.1"
+      }
+    },
     "sortablejs": {
       "version": "1.14.0",
       "resolved": "https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz",

+ 1 - 0
package.json

@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
+    "color": "^4.2.3",
     "element-plus": "^2.7.5",
     "vue": "^3.4.21",
     "vue-drag-resize": "^1.5.4",

+ 73 - 0
src/components/maskedbox/colorSelection.vue

@@ -0,0 +1,73 @@
+<template>
+    <div class="same_row_in upAndDown_padding">
+        <span class="title_12 w_60 default_size" style="flex: none;">{{ title }}</span>
+        <el-color-picker v-model="iconColoril" show-alpha @change="handleColorChange" />
+        <div class="leftmargin_8">
+            <el-input v-model="hexColor" size="small">
+                <template #prefix>
+                    <i style="margin-right: 0px;">#</i>
+                </template>
+            </el-input>
+        </div>
+        <div class="grey_input_bgc leftmargin_8">
+            <el-input-number class="card_number" v-model="alpha" :min="0" :max="1" :step="0.1" size="small"
+                controls-position="right" @change="colorNum" />
+            <span>A</span>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref, watch } from "vue";
+import color from 'color'
+const props = defineProps({
+    iconColor: {
+        type: String,
+        required: true
+    },
+    title: {
+        type: String,
+    }
+})
+const iconColoril = props.iconColor
+const alpha = ref(100);
+const hexColor = ref('');
+// rgba hex颜色格式化
+const handleColorChange = (rgbaStr) => {
+    const hex = color(rgbaStr).hex();
+    const alpha1 = color(rgbaStr).alpha();
+
+    const arrColor = removeChar(hex, "#");
+    return arrColor
+    alpha.value = alpha1
+
+    function removeChar(str: string, charToRemove: string): string {
+        return str.replace(new RegExp(charToRemove, 'g'), '');
+    }
+};
+
+const colorNum = (value: any) => {
+    const rgbaStr = props.iconColor;
+    const newAlpha = value;
+    props.iconColor = adjustAlpha(rgbaStr, newAlpha);
+
+    function adjustAlpha(rgbaStr: string, alpha: number): string {
+        const match = rgbaStr.match(/^rgba\((\d+), (\d+), (\d+), ([^\)]+)\)$/);
+        if (!match) {
+            throw new Error('Invalid RGBA string');
+        }
+        const [r, g, b] = [match[1], match[2], match[3]].map(Number);
+        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
+    }
+}
+
+watch(() => props.iconColor, (newValue) => {
+    if (newValue) {
+        // 初始化hex颜色
+        hexColor.value = handleColorChange(newValue)
+    }
+}, { immediate: true, deep: true })
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 0 - 11
src/components/maskedbox/index.ts

@@ -1,11 +0,0 @@
-// getWidget.ts
-const gets = {} as any
-const modules = import.meta.glob('./*.vue', { eager: true })
-for (let each in modules) {
-    const name = (modules[each] as any).default.__name
-    gets[name] = (modules[each] as any).default
-}
-
-// console.log(gets);
-
-export default gets

+ 1 - 1
src/components/widgets/SceneButton.vue

@@ -2,7 +2,7 @@
     <div class="center_in">
         <div class="card_btn center_in" :style="{ width: config.css.width + 'px', height: config.css.height + 'px' }">
             <div class="bg_item_btn center_in">
-                <el-icon :size="config.config.size" :color="config.config.color">
+                <el-icon :size="config.config.size" :color="config.css.iconColor">
                     <BellFilled />
                 </el-icon>
             </div>

+ 2 - 1
src/module/config/button.ts

@@ -3,7 +3,6 @@ const btnConfig = {
     type: 1,
     name: '文本',
     size: 30,
-    color: "#158cfb",
     isResizable: true, //禁止缩放
     // sticks:['tl', 'tm', 'tr', 'mr', 'br', 'bm', 'bl', 'ml'],
     aspectRatio: false, //禁止等比例缩放
@@ -15,7 +14,9 @@ const btnCss = {
     width: 90,
     height: 90,
     borderRadius: 8,
+    iconColor: "rgba(21, 140, 251, 1)",
     backgroundColor: '#fff',
+    fontWeight: 500,
 }
 
 export { btnConfig, btnCss }

+ 23 - 0
src/style.css

@@ -63,6 +63,29 @@ body,
 .title_12{
     font-size: 12px;
 }
+
 .w_60{
     width: 60px;
+}
+
+.upAndDown_padding{
+    padding: 8px 0px;
+}
+
+.leftmargin_8{
+    margin-left: 8px;
+}
+
+.grey_input_bgc {
+    width: 85px;
+    background-color: #f1f1f7;
+    display: flex;
+    align-items: center;
+    padding: 2px;
+    border-radius: 4px;
+
+    span {
+        font-size: 12px;
+        margin: 1px;
+    }
 }

+ 170 - 14
src/views/maskedbox.vue

@@ -25,8 +25,8 @@
                 <ArrowDown />
             </el-icon>
         </div>
-        <div v-if="basicFlag" style="padding: 9px 0px 4px 18px;">
-            <div class="same_row_in" style="padding: 9px 0px;">
+        <div v-if="basicFlag" class="card_second_level">
+            <div class="same_row_in upAndDown_padding">
                 <span class="title_12 w_60 default_size">尺寸</span>
                 <div class="grey_input_bgc">
                     <el-input-number class="card_number" v-model="config.css.width" :min="1" size="small"
@@ -47,22 +47,97 @@
                     <span>H</span>
                 </div>
             </div>
-            <div>
-
+            <div class="same_row_in upAndDown_padding" v-if="config.config.size">
+                <span class="title_12 w_60 default_size" style="flex: none;">层级</span>
+                <div class="grey_input_bgc w_60_index">
+                    <el-input-number class="card_number" v-model="config.config.size" :min="1" size="small"
+                        controls-position="right" />
+                </div>
+                <div class="card_slider" style="width: 100%;">
+                    <el-slider v-model="config.config.size" size="small" />
+                </div>
+            </div>
+            <div class="same_row_in upAndDown_padding">
+                <span class="title_12 w_60 default_size" style="flex: none;">颜色</span>
+                <el-color-picker v-model="config.css.iconColor" show-alpha @change="handleColorChange" />
+                <div class="leftmargin_8">
+                    <el-input v-model="hexColor" size="small">
+                        <template #prefix>
+                            <i style="margin-right: 0px;">#</i>
+                        </template>
+                    </el-input>
+                </div>
+                <div class="grey_input_bgc leftmargin_8">
+                    <el-input-number class="card_number" v-model="alpha" :min="0" :max="1" :step="0.1" size="small"
+                        controls-position="right" @change="colorNum" />
+                    <span>A</span>
+                </div>
+            </div>
+            <div class="same_row_in upAndDown_padding">
+                <span class="title_12 w_60 default_size" style="flex: none;">字体</span>
+                <div class="grey_input_bgc w_60_index">
+                    <el-input-number class="card_number" v-model="config.config.size" :min="1" size="small"
+                        controls-position="right" />
+                </div>
+                <div class="card_select_bg" style="width: 100%;">
+                    <el-select v-model="config.css.fontWeight" placeholder="Select" size="small">
+                        <el-option v-for="item in fontWeightData" :key="item.value" :label="item.label"
+                            :value="item.value" />
+                    </el-select>
+                </div>
             </div>
         </div>
     </div>
+    <div class="box_padding" v-if="config.css">
+        <div class="same_row_in">
+            <span class="default_size title_5">图标</span>
+            <el-icon style="cursor: pointer;" :class="imgFlag ? '' : 'putAway'" @click="getbasicSetting('img')">
+                <ArrowDown />
+            </el-icon>
+        </div>
+        <div v-if="imgFlag" class="card_second_level">
+            <div class="same_row_in upAndDown_padding">
+                <span class="title_12 w_60 default_size" style="flex: none;">大小</span>
+                <div class="images_card center_in">
+                    <el-image style="width: 16px; height: 16px"
+                        src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg" fit="fill" />
+                </div>
+                <div class="grey_input_bgc w_60_index">
+                    <el-input-number class="card_number" v-model="config.config.size" :min="1" size="small"
+                        controls-position="right" />
+                </div>
+                <div class="card_slider" style="width: 100%;">
+                    <el-slider v-model="config.config.size" size="small" />
+                </div>
+            </div>
+            <colorSelection :iconColor="config.css.iconColor" title="选择颜色"></colorSelection>
+        </div>
+    </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
+import { ref, watch } from "vue";
+import color from 'color';
+import colorSelection from '../components/maskedbox/colorSelection.vue';
+
 const props = defineProps({
     config: {
         type: Object,
         required: true
     },
 })
+const fontWeightData = [{
+    label: '细体',
+    value: 300,
+}, {
+    label: '常规',
+    value: 400,
+}, {
+    label: '粗体',
+    value: 500,
+}]
 const basicFlag = ref(true)
+const imgFlag = ref(true)
 const lockFlag = ref(true)
 function getbasicSetting(params: any) {
     console.log();
@@ -72,6 +147,12 @@ function getbasicSetting(params: any) {
         } else {
             basicFlag.value = true
         }
+    } else if (params == 'img') {
+        if (imgFlag.value) {
+            imgFlag.value = false
+        } else {
+            imgFlag.value = true
+        }
     }
 }
 function getLock(params: any) {
@@ -81,7 +162,44 @@ function getLock(params: any) {
         lockFlag.value = true
     }
 }
-console.log(props.config, 888)
+
+const alpha = ref(1);
+const hexColor = ref('');
+// rgba hex颜色格式化
+const handleColorChange = (rgbaStr) => {
+    const hex = color(rgbaStr).hex();
+    const alpha1 = color(rgbaStr).alpha();
+
+    const arrColor = removeChar(hex, "#");
+    return arrColor
+    alpha.value = alpha1
+
+    function removeChar(str: string, charToRemove: string): string {
+        return str.replace(new RegExp(charToRemove, 'g'), '');
+    }
+};
+
+const colorNum = (value: any) => {
+    const rgbaStr = props.config.css.iconColor;
+    const newAlpha = value;
+    props.config.css.iconColor = adjustAlpha(rgbaStr, newAlpha);
+
+    function adjustAlpha(rgbaStr: string, alpha: number): string {
+        const match = rgbaStr.match(/^rgba\((\d+), (\d+), (\d+), ([^\)]+)\)$/);
+        if (!match) {
+            throw new Error('Invalid RGBA string');
+        }
+        const [r, g, b] = [match[1], match[2], match[3]].map(Number);
+        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
+    }
+}
+
+watch(() => props.config, (newValue) => {
+    if (newValue.css) {
+        // 初始化hex颜色
+        hexColor.value = handleColorChange(newValue.css.iconColor)
+    }
+}, { immediate: true, deep: true })
 </script>
 
 <style lang="scss" scoped>
@@ -89,6 +207,10 @@ console.log(props.config, 888)
     padding: 7px 0px 4px;
 }
 
+.card_second_level {
+    padding: 9px 0px 4px 18px;
+}
+
 .dpjis {
     width: 159px;
     height: 100px;
@@ -139,17 +261,51 @@ console.log(props.config, 888)
     width: 30px;
 }
 
-.grey_input_bgc {
-    width: 85px;
+
+.card_select_bg {
     background-color: #f1f1f7;
-    display: flex;
-    align-items: center;
     padding: 2px;
     border-radius: 4px;
+}
 
-    span {
-        font-size: 12px;
-        margin: 1px;
-    }
+.w_60_index {
+    width: 60px !important;
+    margin-right: 5px;
+}
+
+.card_slider :deep(.el-slider__button-wrapper) {
+    top: -17px;
+}
+
+.card_slider :deep(.el-slider__runway) {
+    height: 4px !important;
+}
+
+.card_slider :deep(.el-slider__bar) {
+    height: 4px !important;
+}
+
+.card_slider :deep(.el-slider__button) {
+    width: 13px;
+    height: 13px;
+}
+
+.cKnghd {
+    flex: none;
+    border: 1px solid rgba(0, 0, 0, 0.2);
+    width: 46px;
+    height: 24px;
+    cursor: pointer;
+    border-radius: 3px;
+}
+
+.images_card {
+    margin-right: 5px;
+    flex: none;
+    width: 28px;
+    height: 28px;
+    cursor: pointer;
+    background-color: rgb(243, 243, 248);
+    border-radius: 4px;
 }
 </style>