Browse Source

Merge branch 'main' of github.com:le5le-com/visualization-design

Alsmile 2 years ago
parent
commit
d7562d40b9

+ 4 - 22
src/views/components/Graphics.vue

@@ -18,8 +18,8 @@
         </div>
       </div>
       <div class="list" :class="showType === 1 ? 'two-list' : ''">
-        <t-collapse v-model:value="panelValue" @change="handlePanelChange">
-          <t-collapse-panel :header="item.name" v-for="item in showList">
+        <t-collapse v-model:value="panelValue">
+          <t-collapse-panel :value="item.name" :header="item.name" v-for="item in showList" :key="item.name">
             <div
               class="show-item"
               v-for="iItem in item.list"
@@ -138,14 +138,12 @@ const getCommponentsLib = async () => {
 
 const getMaterialLib = async () => {
   const pngs = await getPngFolders();
-  console.log("png", pngs);
   return pngs;
 };
 let materialLib: any[] = [];
 
 const getIconsLib = async () => {
   const icons = await getIconFolders();
-  console.log(icons);
   return icons;
 };
 
@@ -172,7 +170,6 @@ const groupChange = async (name: string) => {
       if (materialLib.length === 0) {
         materialLib = await getMaterialLib();
       }
-      console.log(materialLib);
       showList.value = materialLib;
       break;
     case "图标":
@@ -194,22 +191,10 @@ const groupChange = async (name: string) => {
 const showList = ref<any[]>([]);
 const showType = ref(0);
 const panelValue = ref([]);
-const handlePanelChange = (e: any) => {
-  console.log("e", e);
-  // console.log("change", e,panelValue.value);
-  // if (activeGroup.value === '素材') {
-  //   const data:any = materialLib[e[0]];
-  //   console.log("data", data.name);
-  //   if (!data.list || data.list.length === 0) {
-  //     data.list = getPngs(globalThis.folderJson?data.pinyin:data.name)
-  //   }
-  // }
-};
 
 watch(
   () => panelValue.value,
   async (newV: any[], oldV: any[]) => {
-    console.log(newV, oldV);
     const newOpen: any = [];
     for (let v of newV) {
       !oldV.includes(v) && newOpen.push(v);
@@ -217,19 +202,16 @@ watch(
     if (newOpen.length === 0) {
       return;
     }
-    console.log(newOpen);
     if (activeGroup.value === "素材") {
-      const data: any = materialLib[newOpen[0]];
-      console.log("data", data, newOpen[0]);
+      const data: any = materialLib.find(item => item.name === newOpen[0]);//  materialLib[newOpen[0]];
       if (!data.list || data.list.length === 0) {
         data.list = await getPngs(
           globalThis.folderJson ? data.pinyin : data.name
         );
-        console.log(materialLib);
         showList.value = deepClone(materialLib);
       }
     } else if (activeGroup.value === "图标") {
-      const data: any = iconsLib[newOpen[0]];
+      const data: any = iconsLib.find(item => item.name === newOpen[0]);// iconsLib[newOpen[0]];
       if (!data.list || data.list.length === 0) {
         data.list = await getIcons(
           globalThis.folderJson ? data.pinyin : data.name

+ 105 - 55
src/views/components/PenProps.vue

@@ -922,10 +922,21 @@
           <t-divider style="margin: -8px 0" />
           <div class="form-item px-16" style="margin-top: -12px">
             <label style="width: 60px">鼠标提示</label>
-            <t-button shape="square" variant="outline" style="width: 24px">
+            <t-button
+              shape="square"
+              variant="outline"
+              style="width: 24px"
+              @click="showTitle"
+            >
               <t-icon name="ellipsis" slot="icon"
             /></t-button>
           </div>
+          <MonacoModal
+            v-model:visible="titleVisible"
+            :options="titleOptions"
+            title="鼠标提示"
+            @changeOptions="changeTitleCode"
+          />
           <t-space />
         </t-space>
       </t-tab-panel>
@@ -939,16 +950,18 @@
 </template>
 
 <script lang="ts" setup>
-import { onBeforeMount, onUnmounted, reactive, ref } from 'vue';
-import { getCookie } from '@/services/cookie';
-import { useSelection } from '@/services/selections';
+import { onBeforeMount, onUnmounted, reactive, ref } from "vue";
+import { getCookie } from "@/services/cookie";
+import { useSelection } from "@/services/selections";
+import MonacoModal from "./common/MonacoModal.vue";
+import { monacoOption } from "./common/MonacoModal.vue";
 
 import PenAnimates from './PenAnimates.vue';
 
 const headers = {
-  Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
+  Authorization: "Bearer " + (localStorage.token || getCookie("token") || ""),
 };
-const updataData = { directory: '/项目' };
+const updataData = { directory: "/项目" };
 
 const uploadRef = ref();
 
@@ -959,23 +972,23 @@ const data = reactive<any>({
 });
 
 const fonts = [
-  '新宋体',
-  '微软雅黑',
-  '黑体',
-  '楷体',
-  '-apple-system',
-  'BlinkMacSystemFont',
-  'PingFang SC',
-  'Hiragino Sans GB',
-  'Microsoft YaHei UI',
-  'Microsoft YaHei',
-  'fangsong',
-  'Source Han Sans CN',
-  'sans-serif',
-  'serif',
-  'Apple Color Emoji',
-  'Segoe UI Emoji',
-  'Segoe UI Symbol',
+  "新宋体",
+  "微软雅黑",
+  "黑体",
+  "楷体",
+  "-apple-system",
+  "BlinkMacSystemFont",
+  "PingFang SC",
+  "Hiragino Sans GB",
+  "Microsoft YaHei UI",
+  "Microsoft YaHei",
+  "fangsong",
+  "Source Han Sans CN",
+  "sans-serif",
+  "serif",
+  "Apple Color Emoji",
+  "Segoe UI Emoji",
+  "Segoe UI Symbol",
 ];
 
 const { selections } = useSelection();
@@ -998,12 +1011,12 @@ onBeforeMount(() => {
     data.pen.dash = 0;
   }
   if (!data.pen.props.text) {
-    if (data.pen.text || data.pen.name === 'text') {
+    if (data.pen.text || data.pen.name === "text") {
       data.pen.props.text = true;
     }
   }
   if (!data.pen.props.image) {
-    if (data.pen.image || data.pen.name === 'image') {
+    if (data.pen.image || data.pen.name === "image") {
       data.pen.props.image = true;
     }
   }
@@ -1023,27 +1036,27 @@ onBeforeMount(() => {
 
   // 测试代码
   data.pen.props.custom = [
-    { label: '数字', key: 'a', type: 'number', placeholder: '输入提示' },
-    { label: '文本', key: 'b' },
-    { label: '布尔', key: 'c', type: 'bool', placeholder: '输入提示' },
-    { label: '颜色', key: 'd', type: 'color', placeholder: '输入提示' },
+    { label: "数字", key: "a", type: "number", placeholder: "输入提示" },
+    { label: "文本", key: "b" },
+    { label: "布尔", key: "c", type: "bool", placeholder: "输入提示" },
+    { label: "颜色", key: "d", type: "color", placeholder: "输入提示" },
     {
-      label: '下拉框',
-      key: 'd',
-      type: 'select',
+      label: "下拉框",
+      key: "d",
+      type: "select",
       options: [
-        { label: '选项1', value: '1' },
-        { label: '选项2', value: '2' },
+        { label: "选项1", value: "1" },
+        { label: "选项2", value: "2" },
       ],
-      placeholder: '输入提示',
+      placeholder: "输入提示",
     },
   ];
   // end
   data.pen.shadow = !!data.pen.shadowColor;
   getRect();
-  meta2d.on('translatePens', getRect);
-  meta2d.on('resizePens', getRect);
-  meta2d.on('rotatePens', getRect);
+  meta2d.on("translatePens", getRect);
+  meta2d.on("resizePens", getRect);
+  meta2d.on("rotatePens", getRect);
 });
 
 const getRect = () => {
@@ -1064,25 +1077,25 @@ const decimalRound = (val: number) => {
 const changeValue = (prop: string) => {
   const v: any = { id: data.pen.id };
   v[prop] = data.pen[prop];
-  if (prop === 'x') {
+  if (prop === "x") {
     v.x = data.rect.x;
-  } else if (prop === 'y') {
+  } else if (prop === "y") {
     v.y = data.rect.y;
-  } else if (prop === 'width') {
+  } else if (prop === "width") {
     v.height = (data.rect.width / data.pen.width) * data.pen.height;
-  } else if (prop === 'height') {
+  } else if (prop === "height") {
     v.width = (data.rect.height / data.pen.height) * data.pen.width;
-  } else if (prop === 'shadow') {
+  } else if (prop === "shadow") {
     if (v[prop]) {
       !v.shadowOffsetX && (v.shadowOffsetX = 0);
       !v.shadowOffsetY && (v.shadowOffsetY = 0);
       !v.shadowBlur && (v.shadowBlur = 0);
     } else {
-      v.shadowColor = '';
+      v.shadowColor = "";
     }
-  } else if (prop === 'lineGradientColors') {
+  } else if (prop === "lineGradientColors") {
     //@ts-ignore
-    if (meta2d.store.active[0].name === 'line') {
+    if (meta2d.store.active[0].name === "line") {
       //@ts-ignore
       meta2d.store.active[0].calculative.gradientColorStop = null;
     } else {
@@ -1090,6 +1103,8 @@ const changeValue = (prop: string) => {
       meta2d.store.active[0].calculative.lineGradient = null;
     }
     //不同模式切换不同的系统配色
+  } else if (prop === "titleFnJs") {
+    v.titleFn = null;
   }
   meta2d.setValue(v);
 };
@@ -1101,7 +1116,7 @@ const onFontPopupVisible = (val: boolean) => {
 const onFontFamily = (fontFamily: string) => {
   data.pen.fontFamily = fontFamily;
   data.fontFamilyPopupVisible = false;
-  changeValue('fontFamily');
+  changeValue("fontFamily");
 };
 
 const fileSuccessed = async (content: any) => {
@@ -1112,7 +1127,7 @@ const fileSuccessed = async (content: any) => {
 };
 
 const fileRemoved = () => {
-  meta2d.setBackgroundImage('');
+  meta2d.setBackgroundImage("");
   meta2d.store.patchFlagsBackground = true;
   meta2d.render();
   data.background = [];
@@ -1128,30 +1143,65 @@ const onSelectTag = (tag: string) => {
     return;
   }
   data.pen.tags.push(tag);
-  changeValue('tags');
+  changeValue("tags");
 };
 
 const onChangeInputTag = (currentTags: any, context: any) => {
   const { trigger, index, item } = context;
-  if (['tag-remove', 'backspace'].includes(trigger)) {
+  if (["tag-remove", "backspace"].includes(trigger)) {
     data.pen.tags.splice(index, 1);
   }
-  if (trigger === 'enter') {
+  if (trigger === "enter") {
     onSelectTag(item);
     const d = meta2d.store.data as any;
     if (!d.groups.includes(item)) {
       d.groups.push(item);
       data.groups = d.groups;
     }
-    data.inputTag = '';
+    data.inputTag = "";
   }
   data.tagPopupVisible = false;
 };
 
+const titleVisible = ref(false);
+const titleOptions: monacoOption[] = [
+  {
+    key: "title",
+    value: 0,
+    name: "文本",
+    tip: "支持markdown",
+    code: "",
+    language: "markdown",
+  },
+  {
+    key: "titleFnJs",
+    value: 1,
+    name: "高级",
+    tip: "mark函数",
+    code: "",
+    language: "javascript",
+    example:'//例如: return `${pen.name}<br/>${pen.text}`;'
+  },
+];
+
+const showTitle = () => {
+  titleOptions.forEach((item) => {
+    item.code = data.pen[item.key] || "";
+  });
+  titleVisible.value = true;
+};
+
+const changeTitleCode = (options: monacoOption[]) => {
+  options.forEach((item) => {
+    data.pen[item.key] = item.code || "";
+    changeValue(item.key);
+  });
+};
+
 onUnmounted(() => {
-  meta2d.off('translatePens', getRect);
-  meta2d.off('resizePens', getRect);
-  meta2d.off('rotatePens', getRect);
+  meta2d.off("translatePens", getRect);
+  meta2d.off("resizePens", getRect);
+  meta2d.off("rotatePens", getRect);
 });
 </script>
 <style lang="postcss" scoped>

+ 62 - 11
src/views/components/common/MonacoModal.vue

@@ -7,10 +7,33 @@
     :on-cancel="cancel"
     :on-close="cancel"
   >
+  <t-radio-group
+      v-if="options"
+      size="small"
+      v-model="currentValue"
+      :default-value="0"
+      @change="changeOption"
+    >
+    <t-tooltip  v-for="option in options" :content="option.tip" placement="top">
+      <t-radio-button  :value="option.value">  {{ option.name }}</t-radio-button>
+      </t-tooltip>
+    </t-radio-group>
     <div ref="monacoDom" class="monaco"></div>
   </t-dialog>
 </template>
+<script lang="ts">
 
+export interface monacoOption {
+  key: string;
+  value?: number | string;
+  name?: string;
+  tip?: string;
+  code?: string;
+  language: "javascript" | "json" | "markdown";
+  example?: string;
+}
+
+</script>
 <script setup lang="ts">
 import {
   defineComponent,
@@ -51,17 +74,26 @@ const props = defineProps({
       return ["javascript", "json", "markdown"].includes(value);
     },
   },
+  options: {
+    type:Array as PropType<monacoOption[]>
+  }
 });
 
-const emit = defineEmits(["update:visible", "changeCode"]);
+const emit = defineEmits(["update:visible", "changeCode","changeOptions"]);
 
 let editor: any = null;
 
 function handleOk() {
   // 按下确认以后修改外界值
-  const code = editor.getValue();
-  emit("changeCode", code);
-  emit("update:visible", false);
+  if (props.options) {
+    props.options[currentValue.value].code = editor.getValue();
+    emit('changeOptions', props.options);
+    emit("update:visible", false);
+  } else {
+    const code = editor.getValue();
+    emit("changeCode", code);
+    emit("update:visible", false);
+  }
 }
 
 function cancel() {
@@ -71,6 +103,19 @@ function cancel() {
 const curTheme = "vs-dark"; // 暗主题
 const monacoDom: any = ref(null);
 
+const currentValue = ref(0);
+let beforeValue = 0;
+const changeOption = (e: number) => {
+  if (editor && props.options) {
+    if (beforeValue !== e) {
+      props.options[beforeValue].code = editor.getValue();
+      beforeValue = e;
+    }
+    monaco.editor.setModelLanguage(editor.getModel(), props.options[e].language || 'javascript');
+    editor.setValue(props.options[e].code || props.options[e].example ||"");
+  }
+}
+
 watch(
   () => props.visible,
   (newV) => {
@@ -84,13 +129,19 @@ watch(
             language: props.language,
           });
         }
-        // 可见状态
-        editor.setValue(props.code);
-        monaco.editor.setModelLanguage(editor.getModel(), props.language);
-        // 格式化
-        setTimeout(() => {
-          editor.getAction(["editor.action.formatDocument"])._run();
-        }, 300);
+        if (props.options) {
+          const option = props.options[currentValue.value];
+          editor.setValue(option.code||option.example||'');
+          monaco.editor.setModelLanguage(editor.getModel(), option.language);
+        } else {
+          // 可见状态
+          editor.setValue(props.code);
+          monaco.editor.setModelLanguage(editor.getModel(), props.language);
+        }
+          // 格式化
+          setTimeout(() => {
+            editor.getAction(["editor.action.formatDocument"])._run();
+          }, 300);
       });
     }
   }