Grnetsky 3 долоо хоног өмнө
parent
commit
f5fbec5cd6

+ 187 - 0
src/views/components/PenAnimates.vue

@@ -72,6 +72,7 @@
                 <t-option :key="0" :value="0" :label="$t('水流')"></t-option>
                 <t-option :key="1" :value="1" :label="$t('水珠')"></t-option>
                 <t-option :key="2" :value="2" :label="$t('圆点')"></t-option>
+                <t-option :key="6" :value="6" :label="$t('自定义')"></t-option>
                 <t-option v-if="['polyline','line'].includes(props.pen.lineName)" :key="3" :value="3" :label="$t('箭头')"></t-option>
                 <t-option v-if="['polyline','line'].includes(props.pen.lineName)" :key="4" :value="4" :label="$t('水滴')"></t-option>
               </t-select>
@@ -105,6 +106,49 @@
               <label>{{$t('轨迹间隔')}}</label>
               <t-input-number v-model="item.animateInterval" theme="column" :min="1" @change="changeValue(i)" :placeholder="$t('默认100')"></t-input-number>
             </div>
+
+            <section v-if="item.lineAnimateType===6">
+              <div class="form-item mt-8">
+                <label>图形类型</label>
+                  <t-select v-model="item.lineAnimateElement" placeholder="请选择你的图形类型">
+                    <t-option v-for="item in drawFuncDialog.animateList" :key="item.label" :value="item.value">
+                      <div style="display: flex;justify-content: space-between;align-items: center;">
+                        <span>{{ item.label }}</span>
+                        <edit-icon @click="editeLineAnimateDraw($event,item)"></edit-icon>
+                      </div>
+                    </t-option>
+                    <template #panelBottomContent>
+                      <div class="select-panel-footer">
+                        <t-button theme="primary" variant="text" block @click="editeLineAnimateDraw($event)"
+                        >新增选项</t-button
+                        >
+                      </div>
+                    </template>
+                  </t-select>
+              </div>
+
+              <div class="form-item mt-8">
+                <label>间隔</label>
+                <t-input
+                  v-model="item.lineAnimateDash"
+                >
+                </t-input>
+
+              </div>
+              <div class="form-item mt-8">
+                <label>元素数量</label>
+                <t-input-number
+                    v-model="item.lineAnimateElementCount"
+                    theme="column"
+                    :min="1"
+                    placeholder="无限"
+                    title="缺省无限个"
+                    @change="changeValue(i)"
+                />
+              </div>
+
+            </section>
+
             <div class="form-item mt-8">
               <label>{{$t('反向流动')}}</label>
               <t-switch class="ml-8 mt-8" size="small" v-model="item.animateReverse" @change="changeValue(i)"></t-switch>
@@ -189,6 +233,31 @@
       </div>
     </div>
   </div>
+
+  <t-dialog
+    v-model:visible="drawFuncDialog.show"
+    :header="drawFuncDialog.edit ? '编辑动画元素' : '添加动画元素'"
+    :width="800"
+    :destroy-on-close="true"
+    @confirm="confirmLineDarwFunc"
+    @close="drawFuncDialog.show = false"
+  >
+    <div class="form-item mt-8">
+      <label>名称</label>
+      <t-input
+        v-model="drawFuncDialog.name"
+      ></t-input>
+    </div>
+
+    <div class="form-item mt-8">
+      <label>代码</label>
+      <CodeEditor
+          v-model="drawFuncDialog.code"
+          :hints="userHints"
+          style="height: 400px"
+      ></CodeEditor>
+    </div>
+  </t-dialog>
   <AnimateFrames
     v-if="animate"
     :animate="animate"
@@ -206,8 +275,11 @@ import AnimateFrames from './AnimateFrames.vue';
 import { defaultPureColor } from '@/services/defaults';
 import { MessagePlugin } from 'tdesign-vue-next';
 import {StopCircleIcon, PlayCircleIcon, EditIcon, DeleteIcon} from 'tdesign-icons-vue-next';
+import CodeEditor from "@/views/components/common/CodeEditor.vue";
+
 const { proxy } = getCurrentInstance();
 const $t = proxy.$t
+
 const props = defineProps<{
   pen: any;
 }>();
@@ -253,6 +325,115 @@ const changeAnimateName = (event, item) => {
     item.name = event;
   }
 };
+const drawFuncDialog = ref({
+  show:false,
+  code:'',
+  name:'',
+  _name:'', // 原始name,用于寻找原始数据
+  animateList:[],
+  edit:false
+});
+
+const userHints = ref([])
+function codeHints() {
+  userHints.value = []
+
+  userHints.value.push({
+    obj:"pen",
+    type:'Pen',
+    typeFilePath:'pen.d.ts', // 外部引入类型 从public目录加载的类型文件
+  })
+
+  userHints.value.push({
+    obj:"ctx",
+    type:'CanvasRenderingContext2D', // js DOM 内置类型
+  })
+
+  userHints.value.push({
+    obj:'state',
+    properties:[{
+      label: 'x坐标', // 显示的文本
+      kind: 9, // 图标类型
+      insertText: "x", // 插入的文本
+      detail: "当前动画帧的x坐标"
+    },
+    {
+      label: 'y坐标', // 显示的文本
+      kind: 9, // 图标类型
+      insertText: "y", // 插入的文本
+      detail: "当前动画帧的y坐标"
+    },
+      {
+        label: '旋转角度', // 显示的文本
+        kind: 9, // 图标类型
+        insertText: "rotate", // 插入的文本
+        detail: "当前动画帧的该点的切线斜率"
+      }],
+    trigger:'.'
+  })
+
+  userHints.value.push({
+    obj:"index",
+    type:'number', // js DOM 内置类型
+  })
+}
+
+
+function editeLineAnimateDraw(e,draw) {
+  e.e?
+    e.e.stopPropagation():
+    e.stopPropagation()
+
+  drawFuncDialog.value.edit = !!draw;
+  drawFuncDialog.value.show = true;
+  drawFuncDialog.value.name = draw?.label;
+  drawFuncDialog.value._name = draw?.label;
+  drawFuncDialog.value.code = draw?.code;
+}
+
+const confirmLineDarwFunc = ()=>{
+  if(drawFuncDialog.value.edit) {
+    const code = `(ctx,pen,state,index)=>{
+      ${drawFuncDialog.value.code}
+    }`
+    meta2d.updateLineAnimateDraws(drawFuncDialog.value._name,{
+      name:drawFuncDialog.value.name,
+      code
+    });
+  }else{
+    addLineDarwFunc()
+  }
+  syncLineAnimateDraws()
+  drawFuncDialog.value.show = false;
+}
+const syncLineAnimateDraws = ()=>{
+  // 获取所有动画类型
+  drawFuncDialog.value.animateList = [];
+  Object.entries(meta2d.store.data.lineAnimateDraws).forEach(([name, func]) => {
+
+    const match = func.match(/\(ctx,\s*pen,\s*state,\s*index\)\s*=>\s*\{([\s\S]*?)\}$/);
+    if(match){
+      const functionBody = match[1].trim();
+
+      drawFuncDialog.value.animateList.push({
+        label: name,
+        value: name,
+        code: functionBody
+      })
+    }
+  })
+}
+
+const addLineDarwFunc = ()=>{
+  if(!drawFuncDialog.value.name) {
+    MessagePlugin.warning('请输入名称!');
+    return;
+  }
+  const code = `(ctx,pen,state,index)=>{
+      ${drawFuncDialog.value.code}
+    }`
+  meta2d.registerLineAnimateDraws(drawFuncDialog.value.name,code);
+}
 
 const penTree: any = ref([]);
 const groups: any = ref([]);
@@ -401,7 +582,13 @@ onBeforeMount(() => {
   if (!props.pen.animations) {
     props.pen.animations = [];
   }
+  syncLineAnimateDraws()
+  codeHints()
 
+  if(props.pen.type && props.pen.lineAnimateType === 6){
+    // 若为自定义类型
+    drawFuncDialog.value.name = props.pen.lineAnimateElement;
+  }
   const p = meta2d.findOne(props.pen.id);
   if (p?.calculative?.start) {
     // @ts-ignore