Alsmile 2 years ago
parent
commit
cb66f38a3a

File diff suppressed because it is too large
+ 197 - 176
pnpm-lock.yaml


+ 18 - 0
src/styles/props.css

@@ -128,6 +128,7 @@
     svg {
       width: 16px;
       color: var(--td-text-color-primary);
+      flex-shrink: 0;
 
       &:hover {
         color: var(--color-primary);
@@ -188,4 +189,21 @@
       background: none;
     }
   }
+
+  .t-tab-panel {
+    height: calc(100vh - 81px);
+    overflow-x: hidden;
+    overflow-y: auto;
+  }
+
+  .t-input {
+    height: 30px;
+    background: none;
+    border: 1px solid var(--color-border-input);
+  }
+
+  ::-webkit-scrollbar {
+    width: 2px;
+    height: 6px;
+  }
 }

+ 30 - 6
src/styles/tdesign.css

@@ -278,14 +278,9 @@
   display: inline-block;
 }
 
-.t-tab-panel {
-  height: calc(100vh - 81px);
-  overflow-y: auto;
-}
-
 .t-tabs__nav-container {
   &.t-is-top::after {
-    background-color: var(--color-border-input);
+    background-color: var(--color-background-input);
   }
 }
 
@@ -397,3 +392,32 @@
     }
   }
 }
+
+.t-message {
+  color: #000000e6;
+  background-color: #ffffff;
+  padding: 10px 16px;
+}
+
+.t-popup__arrow {
+  &::before {
+    background-color: var(--color-background-popup);
+    box-shadow: none;
+  }
+}
+
+.t-popup[data-popper-placement^='top'] .t-popup__arrow::before {
+  top: -4px;
+}
+
+.t-button--variant-base {
+  color: #000000e6;
+
+  &:hover {
+    color: #000000e6;
+  }
+
+  &.t-button--theme-primary {
+    color: #ffffff !important;
+  }
+}

+ 3 - 3
src/views/Index.vue

@@ -5,7 +5,7 @@
     <div class="design-body">
       <Graphics />
       <View />
-      <div>
+      <div style="border-left: 1px solid var(--color-border); z-index: 1">
         <FileProps v-if="selections.mode === SelectionMode.File" />
         <PenProps v-else-if="selections.mode === SelectionMode.Pen" />
         <PensProps v-else />
@@ -17,7 +17,7 @@
 <script lang="ts" setup>
 import { onUnmounted, nextTick } from 'vue';
 import axios from 'axios';
-import { Pen } from '@meta2d/core';
+// import { Pen } from "@meta2d/core";
 
 import Header from './components/Header.vue';
 import Graphics from './components/Graphics.vue';
@@ -97,7 +97,7 @@ onUnmounted(() => {
 
   .design-body {
     display: grid;
-    grid-template-columns: 300px 1fr 300px;
+    grid-template-columns: 300px 1fr 301px;
     height: calc(100vh - 40px);
     border-top: 1px solid var(--color-border);
   }

+ 151 - 13
src/views/components/ElementTree.vue

@@ -19,7 +19,16 @@
           </template>
           <t-icon v-else name="control-platform" />
 
-          {{ node.label }}
+          <t-input
+            v-if="node.data.edited"
+            v-model="node.data.label"
+            :autofocus="true"
+            @blur="onDescription(node)"
+            @enter="onDescription(node)"
+          />
+          <span v-else @dblclick="node.data.edited = true">
+            {{ node.label }}
+          </span>
         </div>
       </template>
       <template #operations="{ node }: any">
@@ -77,10 +86,48 @@
         </div>
       </template>
     </t-tree>
-    <div class="groups">
-      <div class="flex middle between">
-        <div class="title" style="margin-bottom: 8px">图层分组</div>
-        <a> +新建分组</a>
+    <div class="groups" style="padding: 8px 0">
+      <div class="flex middle between" style="padding: 0 12px">
+        <div class="title">图层</div>
+        <a @click="addLayer"> +新建图层</a>
+      </div>
+      <div class="layers">
+        <div
+          v-for="(item, i) in data.layers"
+          class="flex middle between hover"
+          :class="{ primary: i == data.activedLayer }"
+        >
+          <span
+            class="flex-grow"
+            v-if="i != data.editedLayer"
+            @click="activeLayer(i)"
+            @dblclick="
+              data.activedLayer = data.editedLayer = i;
+              data.layer = item;
+            "
+          >
+            {{ item }}
+          </span>
+          <t-input
+            v-else
+            v-model="data.layer"
+            :autofocus="true"
+            @blur="setLayer"
+            @enter="setLayer"
+          />
+          <t-popconfirm
+            content="确认删除该图层吗?"
+            @confirm="delLayer"
+            @cancel="data.deleteLayer = undefined"
+          >
+            <t-icon
+              name="delete"
+              class="ml-8"
+              :class="{ block: i == data.deleteLayer }"
+              @click="data.deleteLayer = i"
+            />
+          </t-popconfirm>
+        </div>
       </div>
     </div>
   </div>
@@ -89,11 +136,13 @@
 <script lang="ts" setup>
 import { onBeforeMount, onBeforeUnmount, reactive, ref } from 'vue';
 import { LockState, Pen } from '@meta2d/core';
+import { MessagePlugin } from 'tdesign-vue-next';
 
 const tree = ref<any>(null);
 const data = reactive<any>({
   tree: [],
   actived: [],
+  layers: [],
 });
 
 onBeforeMount(() => {
@@ -105,6 +154,12 @@ onBeforeMount(() => {
   meta2d.on('combine', getTree);
 
   getTree();
+
+  const d = meta2d.store.data as any;
+  if (!d.layers) {
+    d.layers = [];
+  }
+  data.layers = d.layers;
 });
 
 const getTree = () => {
@@ -175,7 +230,7 @@ const visible = (node: any, v: boolean) => {
   pen && meta2d.setVisible(pen, v);
 };
 
-function setChildrenVisible(node: any, v: boolean) {
+const setChildrenVisible = (node: any, v: boolean) => {
   const children = node.getChildren();
   if (children && children.length > 0) {
     for (const child of children) {
@@ -183,7 +238,72 @@ function setChildrenVisible(node: any, v: boolean) {
       setChildrenVisible(child, v);
     }
   }
-}
+};
+
+const onDescription = (node: any) => {
+  node.data.edited = false;
+  node.setData({ label: node.data.label });
+  meta2d.setValue({
+    id: node.value,
+    description: node.data.label,
+  });
+};
+
+const addLayer = () => {
+  const i = data.layers.length + 1;
+  data.layer = '图层' + i;
+  data.layers.push(data.layer);
+  data.activedLayer = data.editedLayer = i;
+};
+
+const activeLayer = (i: number) => {
+  data.activedLayer = i;
+  const layer = data.layers[i];
+  const pens: Pen[] = [];
+  for (const item of meta2d.store.data.pens) {
+    // @ts-ignore
+    if (item.layer === layer) {
+      pens.push(item);
+    }
+  }
+  meta2d.active(pens, false);
+  meta2d.render();
+};
+
+const setLayer = () => {
+  if (data.layers[data.editedLayer] === data.layer) {
+    data.editedLayer = undefined;
+    return;
+  }
+
+  if (data.layers.includes(data.layer)) {
+    MessagePlugin.error('已经存在相同图层!');
+    return;
+  }
+
+  for (const item of meta2d.store.data.pens) {
+    // @ts-ignore
+    if (item.layer === data.layers[data.editedLayer]) {
+      // @ts-ignore
+      item.layer === data.layer;
+    }
+  }
+
+  data.layers[data.editedLayer] = data.layer;
+  data.editedLayer = undefined;
+};
+
+const delLayer = () => {
+  for (const item of meta2d.store.data.pens) {
+    // @ts-ignore
+    if (item.layer === data.layers[data.deleteLayer]) {
+      // @ts-ignore
+      delete item.layer;
+    }
+  }
+  data.layers.splice(data.deleteLayer, 1);
+  data.deleteLayer = undefined;
+};
 
 onBeforeUnmount(() => {
   meta2d.off('opened', getTree);
@@ -203,18 +323,36 @@ onBeforeUnmount(() => {
   & > * {
     overflow-y: auto;
     width: 100%;
-
-    &::-webkit-scrollbar {
-      width: 2px;
-      height: 6px;
-    }
   }
 
   .groups {
     flex-shrink: 0;
     height: 240px;
-    border-top: 1px solid var(--color-border);
+    border-top: 1px solid var(--color-border-input);
     padding: 8px 12px;
   }
+
+  .layers {
+    height: calc(100% - 24px);
+    overflow-y: auto;
+    padding: 0 12px 16px 12px;
+    & > div {
+      height: 30px;
+      line-height: 30px;
+
+      svg {
+        display: none;
+        &.block {
+          display: block;
+        }
+      }
+
+      &:hover {
+        svg {
+          display: block;
+        }
+      }
+    }
+  }
 }
 </style>

+ 10 - 12
src/views/components/FileProps.vue

@@ -7,7 +7,7 @@
             <label>画布尺寸</label>
             <t-input-number
               label="W"
-              :value="meta2dInfo?.width"
+              :value="data.meta2dData.width"
               placeholder="宽"
               theme="column"
               min="1"
@@ -20,7 +20,7 @@
               placeholder="高"
               theme="column"
               min="1"
-              :value="meta2dInfo?.height"
+              :value="data.meta2dData.height"
               style="width: 80px"
               @change="changeValue($event, 'height')"
             />
@@ -56,7 +56,7 @@
               format="CSS"
               :color-modes="['monochrome']"
               :show-primary-color-preview="false"
-              :value="meta2dInfo?.background"
+              :value="data.meta2dData.background"
               @change="changeValue($event, 'background')"
             />
           </div>
@@ -64,7 +64,7 @@
             <label>背景图片</label>
             <t-upload
               class="ml-8"
-              v-model="bgfile"
+              v-model="data.background"
               action="/api/image/upload"
               theme="image"
               accept="image/*"
@@ -171,7 +171,6 @@
 import { onMounted, reactive, onUnmounted, ref } from 'vue';
 import { getCookie } from '@/services/cookie';
 import ElementTree from './ElementTree.vue';
-import { Meta2dData } from '@meta2d/core';
 import MonacoModal from './common/MonacoModal.vue';
 
 const headers = {
@@ -181,12 +180,10 @@ const updataData = { directory: '/项目' };
 
 const data = reactive<any>({
   tab: 1,
+  background: [],
+  meta2dData: {},
 });
 
-const bgfile = ref<any[]>([]);
-
-const meta2dInfo = ref<Meta2dData | any>();
-
 const screenList = reactive([
   {
     name: '大屏',
@@ -254,10 +251,11 @@ const fileRemoved = () => {
   meta2d.setBackgroundImage('');
   meta2d.store.patchFlagsBackground = true;
   meta2d.render();
-  bgfile.value = [];
+  data.background = [];
 };
 
 const changeValue = (e: any, key: string) => {
+  // @ts-ignore
   meta2d.store.data[key] = e;
   meta2d.render();
   openData();
@@ -286,9 +284,9 @@ function initMeta2dCanvas() {
 }
 
 function openData() {
-  meta2dInfo.value = Object.assign({}, meta2d.store.data);
+  data.meta2dData = Object.assign({}, meta2d.store.data);
   if (meta2d.store.data.bkImage) {
-    bgfile.value = [
+    data.background = [
       {
         name: meta2d.store.data.bkImage,
         url: meta2d.store.data.bkImage,

+ 47 - 48
src/views/components/Graphics.vue

@@ -41,103 +41,103 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, onUnmounted, reactive } from "vue";
+import { onMounted, onUnmounted, reactive } from 'vue';
 
 const groups = reactive([
   {
-    icon: "desktop",
-    name: "场景",
-    key: "",
+    icon: 'desktop',
+    name: '场景',
+    key: '',
     active: false,
   },
   {
-    icon: "root-list",
-    name: "模板",
-    key: "",
+    icon: 'root-list',
+    name: '模板',
+    key: '',
     active: false,
   },
   {
-    icon: "chart",
-    name: "图表",
-    key: "",
+    icon: 'chart',
+    name: '图表',
+    key: '',
     active: false,
   },
   {
-    icon: "control-platform",
-    name: "控件",
-    key: "",
+    icon: 'control-platform',
+    name: '控件',
+    key: '',
     active: false,
   },
   {
-    icon: "file-icon",
-    name: "图标",
-    key: "",
+    icon: 'file-icon',
+    name: '图标',
+    key: '',
     active: false,
   },
   {
-    icon: "chart-bubble",
-    name: "图形",
-    key: "",
+    icon: 'chart-bubble',
+    name: '图形',
+    key: '',
     active: true,
   },
   {
-    icon: "app",
-    name: "我的",
-    key: "",
+    icon: 'app',
+    name: '我的',
+    key: '',
     active: false,
   },
 ]);
 
 const groupChange = (name: string) => {
-  if (name === "图形") {
+  if (name === '图形') {
   }
 };
 
 const showList = [
   {
-    name: "square",
-    icon: "t-icon t-rect",
-    id: "",
+    name: 'square',
+    icon: 't-icon t-rect',
+    id: '',
     data: {
-      text: "正方形",
+      text: '正方形',
       width: 100,
       height: 100,
-      name: "square",
+      name: 'square',
     },
   },
   {
-    name: "rectangle",
-    icon: "t-icon t-rectangle",
+    name: 'rectangle',
+    icon: 't-icon t-rectangle',
     id: 2,
     data: {
-      text: "圆角矩形",
+      text: '圆角矩形',
       width: 200,
       height: 50,
       borderRadius: 0.1,
-      name: "rectangle",
+      name: 'rectangle',
     },
   },
   {
-    name: "circle",
-    icon: "t-icon t-circle",
-    image: "",
+    name: 'circle',
+    icon: 't-icon t-circle',
+    image: '',
     id: 3,
     data: {
-      text: "圆",
+      text: '圆',
       width: 100,
       height: 100,
-      name: "circle",
+      name: 'circle',
     },
   },
   {
-    name: "triangle",
-    icon: "t-icon t-triangle",
+    name: 'triangle',
+    icon: 't-icon t-triangle',
     id: 4,
     data: {
-      text: "三角形",
+      text: '三角形',
       width: 100,
       height: 100,
-      name: "triangle",
+      name: 'triangle',
     },
   },
 ];
@@ -148,7 +148,7 @@ const dragStart = (event: DragEvent, item: any) => {
   }
 
   event.dataTransfer.setData(
-    "Meta2d",
+    'Meta2d',
     JSON.stringify(item.componentData || item.data)
   );
   event.stopPropagation();
@@ -167,20 +167,19 @@ const dragend = (event: any) => {
 };
 
 onMounted(() => {
-  document.removeEventListener("dragstart", dragstart);
-  document.removeEventListener("dragend", dragend);
+  document.removeEventListener('dragstart', dragstart);
+  document.removeEventListener('dragend', dragend);
 });
 
 onUnmounted(() => {
-  document.addEventListener("dragstart", dragstart, false);
-  document.addEventListener("dragend", dragend, false);
+  document.addEventListener('dragstart', dragstart, false);
+  document.addEventListener('dragend', dragend, false);
 });
 </script>
 <style lang="postcss" scoped>
 .graphics {
   display: flex;
   flex-direction: column;
-  border-right: 1px solid var(--color-border);
 
   .input-search {
     flex-shrink: 0;
@@ -190,7 +189,7 @@ onUnmounted(() => {
   .groups {
     display: grid;
     grid-template-columns: 50px 1fr;
-    border-top: 1px solid var(--color-border);
+    border-top: 1px solid var(--color-background-input);
     flex-grow: 1;
     overflow-y: auto;
     font-size: 12px;

+ 25 - 2
src/views/components/PenProps.vue

@@ -1,8 +1,31 @@
 <template>
-  <div class="props"></div>
+  <div class="props">
+    <t-tabs v-model="data.tab">
+      <t-tab-panel :value="1" label="外观">
+        <t-space direction="vertical" class="panel"> </t-space>
+      </t-tab-panel>
+      <t-tab-panel :value="2" label="事件"> </t-tab-panel>
+      <t-tab-panel :value="3" label="动画"> </t-tab-panel>
+      <t-tab-panel :value="4" label="数据"> </t-tab-panel>
+    </t-tabs>
+  </div>
 </template>
 
-<script lang="ts" setup></script>
+<script lang="ts" setup>
+import { reactive } from 'vue';
+import { getCookie } from '@/services/cookie';
+
+const headers = {
+  Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
+};
+const updataData = { directory: '/项目' };
+
+const data = reactive<any>({
+  tab: 1,
+  background: [],
+  meta2dData: {},
+});
+</script>
 <style lang="postcss" scoped>
 .props {
 }

+ 18 - 15
src/views/components/View.vue

@@ -5,10 +5,13 @@
         <a><t-icon name="add" @click="newFile" /></a>
       </t-tooltip>
       <t-tooltip content="保存" placement="bottom">
-        <a> <t-badge dot :showZero="false" :count="dot?1:0"> <t-icon name="save" @click="save(SaveType.Save)" /></t-badge></a>
+        <a>
+          <t-badge dot :showZero="false" :count="dot ? 1 : 0">
+            <t-icon name="save" @click="save(SaveType.Save)" /></t-badge
+        ></a>
       </t-tooltip>
       <t-tooltip content="保存为模板" placement="bottom">
-        <a><t-icon name="layers" @click="save(SaveType.Save,true)" /></a>
+        <a><t-icon name="layers" @click="save(SaveType.Save, true)" /></a>
       </t-tooltip>
       <t-tooltip content="格式化" placement="bottom">
         <a>
@@ -100,22 +103,22 @@
 </template>
 
 <script lang="ts" setup>
-import { Meta2d, Options } from "@meta2d/core";
-import { onMounted, onUnmounted ,watch} from "vue";
-import { registerBasicDiagram } from "@/services/register";
-import { useRouter, useRoute } from "vue-router";
-import { useUser } from "@/services/user";
-import { getLe5le2d } from "@/services/api";
-import { useDot } from "@/services/common";
-import { save , newFile} from "./Header.vue";
+import { Meta2d, Options } from '@meta2d/core';
+import { onMounted, onUnmounted, watch } from 'vue';
+import { registerBasicDiagram } from '@/services/register';
+import { useRouter, useRoute } from 'vue-router';
+import { useUser } from '@/services/user';
+import { getLe5le2d } from '@/services/api';
+import { useDot } from '@/services/common';
+import { save, newFile } from './Header.vue';
 
 const router = useRouter();
 const route = useRoute();
 const { user, message, getUser, getMessage, signout } = useUser();
-const { dot,setDot,getDot} = useDot();
+const { dot, setDot, getDot } = useDot();
 
 const meta2dOptions: Options = {
-  cdn: "https://assets.le5lecdn.com",
+  cdn: 'https://assets.le5lecdn.com',
   rule: true,
   background: '#1e2430',
   x: 32,
@@ -138,7 +141,7 @@ const watcher = watch(
 
 const open = async () => {
   if (route.query.id) {
-    const ret: any = getLe5le2d(route.query.id+'');
+    const ret: any = getLe5le2d(route.query.id + '');
     ret && meta2d.open(ret);
   } else {
     meta2d.open();
@@ -157,7 +160,7 @@ onUnmounted(() => {
   display: flex;
   flex-direction: column;
   background-color: var(--color-background-editor);
-  border-right: 1px solid var(--color-border);
+  border-left: 1px solid var(--color-border);
 
   .tools {
     display: flex;
@@ -186,7 +189,7 @@ onUnmounted(() => {
   }
 
   #meta2d {
-    border-top: 1px solid var(--color-border);
+    border-top: 1px solid var(--color-background-input);
     height: calc(100vh - 81px);
   }
 }

Some files were not shown because too many files changed in this diff