|
@@ -80,26 +80,129 @@
|
|
|
<section v-if="item.lineAnimateType===5">
|
|
|
<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>
|
|
|
- <div style="display: flex;gap: 6px">
|
|
|
- <edit-icon @click="editeLineAnimateDraw($event,item)"></edit-icon>
|
|
|
- <DeleteIcon @click="deleteLineAnimateDraw($event,item)"/>
|
|
|
- </div>
|
|
|
+ <t-tabs v-model="item.lineAnimateTargetType">
|
|
|
+ <t-tab-panel :value="0" label="图片">
|
|
|
+ <div class="mt-8">
|
|
|
+ <t-upload
|
|
|
+ class="ml-8"
|
|
|
+ :showImageFileName="false"
|
|
|
+ action="/api/image/upload"
|
|
|
+ theme="image"
|
|
|
+ accept="image/*"
|
|
|
+ :headers="headers"
|
|
|
+ :data="updataData"
|
|
|
+ @success="fileSuccessed($event,item,i)"
|
|
|
+ @remove="fileRemoved(item,i)"
|
|
|
+ v-model="imagesRef"
|
|
|
+ :auto-upload="true"
|
|
|
+ :upload-all-files-in-one-request="false"
|
|
|
+ />
|
|
|
</div>
|
|
|
- </t-option>
|
|
|
- <template #panelBottomContent>
|
|
|
- <div class="select-panel-footer">
|
|
|
- <t-button theme="primary" variant="text" block @click="editeLineAnimateDraw($event)"
|
|
|
- >新增选项</t-button
|
|
|
- >
|
|
|
+
|
|
|
+ </t-tab-panel>
|
|
|
+ <t-tab-panel :value="1" label="图标">
|
|
|
+ <div class="mt-8">
|
|
|
+ <t-color-picker
|
|
|
+ class="w-full"
|
|
|
+ format="CSS"
|
|
|
+ :enable-alpha="true"
|
|
|
+ :recent-colors="null"
|
|
|
+ :color-modes="['monochrome']"
|
|
|
+ :show-primary-color-preview="false"
|
|
|
+ :clearable="true"
|
|
|
+ v-model="item.iconColor"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ />
|
|
|
+ <i
|
|
|
+ class="ml-8"
|
|
|
+ :class="pen.iconFamily"
|
|
|
+ style="line-height: 30px; height: 30px; color: var(--color)"
|
|
|
+ >
|
|
|
+ {{ pen.lineAnimateIcon }}
|
|
|
+ </i>
|
|
|
+ <a class="ml-12 mt-4" @click="showIconDrawer = true">
|
|
|
+ 选择
|
|
|
+ </a>
|
|
|
+ <t-drawer
|
|
|
+ v-model:visible="showIconDrawer"
|
|
|
+ header="选择图标"
|
|
|
+ :footer="null"
|
|
|
+ >
|
|
|
+ <Iconfonts :urls="data.iconUrls" @change="onChangeIcon" />
|
|
|
+ </t-drawer>
|
|
|
</div>
|
|
|
- </template>
|
|
|
- </t-select>
|
|
|
+ </t-tab-panel>
|
|
|
+ <t-tab-panel :value="2" label="图元">
|
|
|
+ <div
|
|
|
+ class="form-item mt-8 mb-8"
|
|
|
+ >
|
|
|
+ <t-radio-group class="ml-8" v-model="item.temType" @change="item.nextAnimate = ''">
|
|
|
+ <t-radio value="id">图元</t-radio>
|
|
|
+ <t-radio value="tag">组</t-radio>
|
|
|
+ </t-radio-group>
|
|
|
+ </div>
|
|
|
+ <t-tree-select
|
|
|
+ v-if="item.temType === 'id'"
|
|
|
+ v-model="item.lineAnimatePens"
|
|
|
+ :data="penTree"
|
|
|
+ filterable
|
|
|
+ placeholder="无"
|
|
|
+ />
|
|
|
+ <t-select
|
|
|
+ v-else
|
|
|
+ v-model="item.lineAnimatePens"
|
|
|
+ :options="groups"
|
|
|
+ placeholder="组"
|
|
|
+ />
|
|
|
+ </t-tab-panel>
|
|
|
+ <t-tab-panel :value="3" label="代码">
|
|
|
+ <div class="mt-8">
|
|
|
+ <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>
|
|
|
+ <div style="display: flex;gap: 6px">
|
|
|
+ <edit-icon @click="editeLineAnimateDraw($event,item)"></edit-icon>
|
|
|
+ <DeleteIcon @click="deleteLineAnimateDraw($event,item)"/>
|
|
|
+ </div>
|
|
|
+ </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>
|
|
|
+ </t-tab-panel>
|
|
|
+ </t-tabs>
|
|
|
</div>
|
|
|
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>元素宽度</label>
|
|
|
+ <t-input-number
|
|
|
+ theme="column"
|
|
|
+ :min="1"
|
|
|
+ placeholder="单位像素,默认10px"
|
|
|
+ v-model="item.lineAnimateElementWidth"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ ></t-input-number>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>元素高度</label>
|
|
|
+ <t-input-number
|
|
|
+ theme="column"
|
|
|
+ :min="1"
|
|
|
+ placeholder="单位像素,默认10px"
|
|
|
+ v-model="item.lineAnimateElementHeight"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ ></t-input-number>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
<div class="form-item mt-8">
|
|
|
<label>间隔</label>
|
|
|
<t-input
|
|
@@ -122,47 +225,64 @@
|
|
|
</div>
|
|
|
|
|
|
</section>
|
|
|
-
|
|
|
- <div class="form-item mt-8">
|
|
|
- <label>{{$t('运动速度')}}</label>
|
|
|
- <t-slider class="ml-12" v-model="item.animateSpan" :show-tooltip="true" :min="1" :max="10" @change="changeValue(i)"></t-slider>
|
|
|
- </div>
|
|
|
<div class="form-item mt-8">
|
|
|
- <label>{{$t('动画颜色')}}</label>
|
|
|
- <t-color-picker class="w-full" format="CSS" :enable-alpha="true" :recent-colors="null" :swatch-colors="defaultPureColor" :color-modes="['monochrome']" :show-primary-color-preview="false" :clearable="true" v-model="item.animateColor" @change="changeValue(i)"></t-color-picker>
|
|
|
+ <label>时间函数</label>
|
|
|
+ <t-switch
|
|
|
+ class="ml-8 mt-8"
|
|
|
+ size="small"
|
|
|
+ v-model="item.curveAnimate"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ ></t-switch>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="form-item mt-8">
|
|
|
- <label>动画时长
|
|
|
- <t-tooltip content="需配置时间曲线使用,单独设置无效" placement="right">
|
|
|
- <HelpCircleIcon style="font-size: 14px" class="ml-4 hover"/>
|
|
|
- </t-tooltip></label>
|
|
|
- <t-input-number
|
|
|
- theme="column"
|
|
|
+ <div class="form-item mt-8" v-if="!item.curveAnimate">
|
|
|
+ <label>运动速度</label>
|
|
|
+ <t-slider
|
|
|
+ class="ml-12"
|
|
|
+ v-model="item.animateSpan"
|
|
|
+ :show-tooltip="true"
|
|
|
:min="1"
|
|
|
- placeholder="动画运行时长,单位秒"
|
|
|
- v-model="item.duration"
|
|
|
+ :max="10"
|
|
|
@change="changeValue(i)"
|
|
|
- ></t-input-number>
|
|
|
+ />
|
|
|
</div>
|
|
|
+ <section v-else>
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>动画时长</label>
|
|
|
+ <t-input-number
|
|
|
+ theme="column"
|
|
|
+ :min="1"
|
|
|
+ placeholder="单位秒,默认5秒"
|
|
|
+ v-model="item.duration"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ ></t-input-number>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-item mt-8">
|
|
|
+ <label>时间曲线</label>
|
|
|
+
|
|
|
+ <BezierEditor
|
|
|
+ style="width: 200px"
|
|
|
+ v-model="item.animateTimingFunction"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ :preset="bezierPreset"
|
|
|
+ ></BezierEditor>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
|
|
|
<div class="form-item mt-8">
|
|
|
- <label>时间曲线
|
|
|
- <t-tooltip content="需同时配置动画时长,并且运动速度配置将失效" placement="right">
|
|
|
- <HelpCircleIcon style="font-size: 14px" class="ml-4 hover"/>
|
|
|
- </t-tooltip>
|
|
|
- </label>
|
|
|
-
|
|
|
- <BezierEditor
|
|
|
- style="width: 200px"
|
|
|
- v-model="item.animateTimingFunction"
|
|
|
- @change="changeValue(i)"
|
|
|
- :preset="bezierPreset"
|
|
|
- ></BezierEditor>
|
|
|
+ <label>{{$t('动画颜色')}}</label>
|
|
|
+ <t-color-picker class="w-full" format="CSS" :enable-alpha="true" :recent-colors="null" :swatch-colors="defaultPureColor" :color-modes="['monochrome']" :show-primary-color-preview="false" :clearable="true" v-model="item.animateColor" @change="changeValue(i)"></t-color-picker>
|
|
|
</div>
|
|
|
+
|
|
|
+
|
|
|
<div class="form-item mt-8">
|
|
|
<label>{{$t('发光效果')}}</label>
|
|
|
- <t-switch class="ml-8 mt-8" size="small" v-model="item.animateShadow" @change="changeValue(i)"></t-switch>
|
|
|
+ <t-switch
|
|
|
+ class="ml-8 mt-8"
|
|
|
+ size="small"
|
|
|
+ v-model="item.animateShadow"
|
|
|
+ @change="changeValue(i)"
|
|
|
+ />
|
|
|
</div>
|
|
|
<div v-if="item.animateShadow" class="form-item mt-8">
|
|
|
<label>{{$t('发光颜色')}}</label>
|
|
@@ -306,11 +426,13 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { onBeforeMount, ref, watch, onUnmounted,onBeforeUnmount,getCurrentInstance } from 'vue';
|
|
|
+import { onBeforeMount, ref, watch, onUnmounted,onBeforeUnmount,getCurrentInstance,computed, reactive } from 'vue';
|
|
|
|
|
|
-import { getPenTree } from '@/services/common';
|
|
|
+import {autoSave, getPenTree} from '@/services/common';
|
|
|
import { deepClone } from '@meta2d/core';
|
|
|
|
|
|
+import { getToken } from '@le5le/auth-token';
|
|
|
+
|
|
|
import AnimateFrames from './AnimateFrames.vue';
|
|
|
import { defaultPureColor } from '@/services/defaults';
|
|
|
import { MessagePlugin } from 'tdesign-vue-next';
|
|
@@ -318,6 +440,8 @@ import {StopCircleIcon, PlayCircleIcon, EditIcon, DeleteIcon, HelpCircleIcon} fr
|
|
|
import CodeEditor from "@/views/components/common/CodeEditor.vue";
|
|
|
import {cdn} from "@/services/api";
|
|
|
import BezierEditor from "@/views/components/common/BezierEditor.vue";
|
|
|
+import Iconfonts from "@/views/components/common/Iconfonts.vue";
|
|
|
+import {s8} from "@/services/random";
|
|
|
|
|
|
const { proxy } = getCurrentInstance();
|
|
|
const $t = proxy.$t
|
|
@@ -348,12 +472,54 @@ function changeAnimateAutoPlay(value, item) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const updataData = { directory: '/大屏/图片/默认' };
|
|
|
+const headers = {
|
|
|
+ Authorization: 'Bearer ' + (getToken() || ''),
|
|
|
+};
|
|
|
+
|
|
|
const bezierPreset = [
|
|
|
'0.25,0.25,0.75,0.75',
|
|
|
'0.25,0.1,0.25,1',
|
|
|
'0.42,0,0.58,1',
|
|
|
'0,0,0.58,1',
|
|
|
]
|
|
|
+
|
|
|
+const imagesRef = ref(
|
|
|
+ props.pen.lineAnimateImages?.map((i) => ({ name: i, url: i })) || []
|
|
|
+)
|
|
|
+
|
|
|
+const showIconDrawer = ref(false)
|
|
|
+
|
|
|
+const data = reactive<any>({
|
|
|
+ iconUrls:[]
|
|
|
+});
|
|
|
+
|
|
|
+const onChangeIcon = (params: any) => {
|
|
|
+
|
|
|
+ // Object.assign(props.pen, params);
|
|
|
+ meta2d.setValue({
|
|
|
+ id: props.pen.id,
|
|
|
+ lineAnimateIcon: params.icon,
|
|
|
+ iconFamily: params.iconFamily,
|
|
|
+ });
|
|
|
+ autoSave(true);
|
|
|
+ showIconDrawer.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+watch(imagesRef, (val) => {
|
|
|
+ meta2d.setValue({
|
|
|
+ id: props.pen.id,
|
|
|
+ lineAnimateImages: val.map(i => i.url)
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+function fileSuccessed(content,item,i) {
|
|
|
+ changeValue(i)
|
|
|
+}
|
|
|
+
|
|
|
+function fileRemoved(item,i){
|
|
|
+ changeValue(i)
|
|
|
+}
|
|
|
const checkAnimateName = (item:any) => {
|
|
|
if(!item.name) {
|
|
|
MessagePlugin.warning($t('动画名不能为空!'));
|
|
@@ -430,8 +596,8 @@ function codeHints() {
|
|
|
kind: 9, // 图标类型
|
|
|
insertText: `const scale = pen.calculative.canvas.store.data.scale;
|
|
|
|
|
|
-const width = 10 // 此处定义图形宽度
|
|
|
-const height = 10 // 此处定义图形高度
|
|
|
+const width = (pen.lineAnimateElementWidth || 10);
|
|
|
+const height = (pen.lineAnimateElementHeight || 10) ;
|
|
|
|
|
|
ctx.translate(state.x + (width/2 * scale), state.y + (height/2 * scale)); // 平移到中心点
|
|
|
ctx.rotate((state.rotate * Math.PI) / 180); // 配置旋转角度
|
|
@@ -689,6 +855,10 @@ onBeforeMount(() => {
|
|
|
groups.value.push({ label: item, value: item });
|
|
|
}
|
|
|
}
|
|
|
+ if (!d.iconUrls) {
|
|
|
+ d.iconUrls = [];
|
|
|
+ }
|
|
|
+ data.iconUrls = d.iconUrls;
|
|
|
});
|
|
|
onBeforeUnmount(() => {
|
|
|
meta2d.off('animateEnd', cancleAnimatePlayState);
|
|
@@ -715,7 +885,8 @@ const addAnimate = () => {
|
|
|
openedCollapses.value.push(props.pen.animations.length);
|
|
|
props.pen.animations.push({
|
|
|
name: $t('动画') + (props.pen.animations.length + 1),
|
|
|
- temType: 'id'
|
|
|
+ temType: 'id',
|
|
|
+ lineAnimateTargetType:0
|
|
|
});
|
|
|
};
|
|
|
|
|
@@ -805,4 +976,26 @@ onUnmounted(() => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+.props .t-tab-panel{
|
|
|
+ height: auto;
|
|
|
+}
|
|
|
+:deep(.t-tabs__nav-item.t-size-m){
|
|
|
+ height: auto;
|
|
|
+}
|
|
|
+:deep(.t-tabs){
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+:deep(.t-tabs__nav-item-wrapper){
|
|
|
+ padding: 0 0;
|
|
|
+}
|
|
|
+:deep(.t-tabs__nav-wrap){
|
|
|
+ justify-content: space-around;
|
|
|
+}
|
|
|
+:deep(.t-tabs__nav-scroll){
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+:deep(.t-tabs__bar){
|
|
|
+ display: none;
|
|
|
+}
|
|
|
</style>
|