diff --git a/README.md b/README.md index a05f81d..657a682 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,10 @@ vue2建议使用iframe集成,目前没有vue2的版本,如果您接受不了 [秀英童鞋](https://blog.csdn.net/qq_42862247)对此项目前进的耐心指导 +[一个低代码(可视化拖拽)教学项目](https://github.com/woai3c/visual-drag-demo) + +还在坚持用原生`svg`进行组态的开发者们 + ## 捐助 如果这个项目对您有所帮助,请扫下方二维码打赏一杯咖啡。 diff --git a/package.json b/package.json index 1e4504c..2dc6a29 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "ace-builds": "^1.14.0", + "animate.css": "^4.1.1", "echarts": "^5.4.1", "element-plus": "^2.2.9", "pinia": "^2.0.16", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9dbe2e..d64d85a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ specifiers: '@typescript-eslint/parser': ^5.30.5 '@vitejs/plugin-vue': ^2.3.3 ace-builds: ^1.14.0 + animate.css: ^4.1.1 echarts: ^5.4.1 element-plus: ^2.2.9 eslint: ^8.19.0 @@ -33,6 +34,7 @@ specifiers: dependencies: ace-builds: 1.14.0 + animate.css: 4.1.1 echarts: 5.4.1 element-plus: 2.2.9_vue@3.2.37 pinia: 2.0.17_j6bzmzd4ujpabbp5objtwxyjp4 @@ -815,6 +817,10 @@ packages: uri-js: 4.4.1 dev: true + /animate.css/4.1.1: + resolution: {integrity: sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==} + dev: false + /ansi-regex/2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} diff --git a/src/assets/icons/setting.svg b/src/assets/icons/setting.svg new file mode 100644 index 0000000..8f147ad --- /dev/null +++ b/src/assets/icons/setting.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/src/components/webtopo-svg-edit/components/center-panel/index.vue b/src/components/webtopo-svg-edit/components/center-panel/index.vue index dc15d8a..aaea1b4 100644 --- a/src/components/webtopo-svg-edit/components/center-panel/index.vue +++ b/src/components/webtopo-svg-edit/components/center-panel/index.vue @@ -70,6 +70,7 @@ item.actual_bound.x + item.actual_bound.width / 2 )},${-(item.actual_bound.y + item.actual_bound.height / 2)})`" + :class="`${getCommonClass(item)}`" > + {{ + common_animate_list + .map((m) => m.children) + .reduce((pre, curr) => { + return pre.concat(curr); + }) + .find((f) => f.value == select_val)?.label + }} + + 新增 + + + + +
+
+
+ {{ animate.label }} +
+
+
+
+
+
+ + + + diff --git a/src/components/webtopo-svg-edit/components/right-panel/index.vue b/src/components/webtopo-svg-edit/components/right-panel/index.vue index 30f7e3d..f27d8bc 100644 --- a/src/components/webtopo-svg-edit/components/right-panel/index.vue +++ b/src/components/webtopo-svg-edit/components/right-panel/index.vue @@ -78,6 +78,46 @@ :obj-info="globalStore.handle_svg_info.info.animations" > + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -95,13 +135,16 @@ ElTabPane, TabsPaneContext, ElInput, - ElSwitch + ElSwitch, + ElSelect, + ElOption } from 'element-plus'; import { ref } from 'vue'; import { useConfigStore } from '@/store/config'; import { useGlobalStore } from '@/store/global'; - import { EGlobalStoreIntention } from '@/store/global/types'; + import { EGlobalStoreIntention, IDoneJson } from '@/store/global/types'; import DynamicElFormItem from './dynamic-el-form-item.vue'; + import CommonAnimate from './common-animate.vue'; const configStore = useConfigStore(); const globalStore = useGlobalStore(); @@ -109,4 +152,9 @@ const handleClick = (tab: TabsPaneContext, event: Event) => { console.log(tab, event); }; + const updateCommonAniVal = (item: IDoneJson | undefined, val: string) => { + if (item?.common_animations) { + item.common_animations.val = val; + } + }; diff --git a/src/components/webtopo-svg-edit/index.vue b/src/components/webtopo-svg-edit/index.vue index dcaf9ce..5248d69 100644 --- a/src/components/webtopo-svg-edit/index.vue +++ b/src/components/webtopo-svg-edit/index.vue @@ -86,6 +86,7 @@ import { useImportDataModel } from '@/hooks'; import { useGlobalStore } from '@/store/global'; import { IDoneJson } from '@/store/global/types'; + import 'animate.css'; const props = defineProps({ customToolBar: { type: Object as PropType, diff --git a/src/components/webtopo-svg-preview/index.vue b/src/components/webtopo-svg-preview/index.vue index 16a5372..894750d 100644 --- a/src/components/webtopo-svg-preview/index.vue +++ b/src/components/webtopo-svg-preview/index.vue @@ -50,6 +50,7 @@ item.actual_bound.x + item.actual_bound.width / 2 )},${-(item.actual_bound.y + item.actual_bound.height / 2)})`" + :class="`${getCommonClass(item)}`" > diff --git a/src/config-center/svg-file/custom-svg/custom-svg-text/index.ts b/src/config-center/svg-file/custom-svg/custom-svg-text/index.ts index 773b294..8ef6994 100644 --- a/src/config-center/svg-file/custom-svg/custom-svg-text/index.ts +++ b/src/config-center/svg-file/custom-svg/custom-svg-text/index.ts @@ -42,5 +42,11 @@ export const custom_svg_text: IConfigItem = { type: EConfigItemPropsType.Color, val: '#FFF200FF' } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/svg-file/have-animation/reservoir/index.ts b/src/config-center/svg-file/have-animation/reservoir/index.ts index 8560009..222c9ea 100644 --- a/src/config-center/svg-file/have-animation/reservoir/index.ts +++ b/src/config-center/svg-file/have-animation/reservoir/index.ts @@ -21,5 +21,11 @@ export const reservoir_svg_file: IConfigItem = { type: EConfigItemPropsType.Color, val: '#000' } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/svg-file/stateful/circuit-breaker/index.ts b/src/config-center/svg-file/stateful/circuit-breaker/index.ts index abe4562..f76c79d 100644 --- a/src/config-center/svg-file/stateful/circuit-breaker/index.ts +++ b/src/config-center/svg-file/stateful/circuit-breaker/index.ts @@ -26,5 +26,11 @@ export const circuit_breaker_svg_file: IConfigItem = { } } } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/svg-file/stateless/alternator/index.ts b/src/config-center/svg-file/stateless/alternator/index.ts index 6918b22..c161d73 100644 --- a/src/config-center/svg-file/stateless/alternator/index.ts +++ b/src/config-center/svg-file/stateless/alternator/index.ts @@ -16,5 +16,11 @@ export const alternator_svg_file: IConfigItem = { type: EConfigItemPropsType.Color, val: '#00ff00' } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/svg-file/stateless/traction-transformer/index.ts b/src/config-center/svg-file/stateless/traction-transformer/index.ts index 73aae3f..255c70d 100644 --- a/src/config-center/svg-file/stateless/traction-transformer/index.ts +++ b/src/config-center/svg-file/stateless/traction-transformer/index.ts @@ -16,5 +16,11 @@ export const traction_transformer_svg_file: IConfigItem = { type: EConfigItemPropsType.Color, val: '#ff0000' } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/system/index.ts b/src/config-center/system/index.ts index cc3aa01..45f678a 100644 --- a/src/config-center/system/index.ts +++ b/src/config-center/system/index.ts @@ -109,3 +109,97 @@ export const connection_line_system: ISystemStraightLine = Object.freeze({ end: null } }); +export const common_animate_list = [ + { + label: '进入', + children: [ + { label: '渐显', value: 'fadeIn' }, + { label: '向右进入', value: 'fadeInLeft' }, + { label: '向左进入', value: 'fadeInRight' }, + { label: '向上进入', value: 'fadeInUp' }, + { label: '向下进入', value: 'fadeInDown' }, + { label: '向右长距进入', value: 'fadeInLeftBig' }, + { label: '向左长距进入', value: 'fadeInRightBig' }, + { label: '向上长距进入', value: 'fadeInUpBig' }, + { label: '向下长距进入', value: 'fadeInDownBig' }, + { label: '旋转进入', value: 'rotateIn' }, + { label: '左顺时针旋转', value: 'rotateInDownLeft' }, + { label: '右逆时针旋转', value: 'rotateInDownRight' }, + { label: '左逆时针旋转', value: 'rotateInUpLeft' }, + { label: '右逆时针旋转', value: 'rotateInUpRight' }, + { label: '弹入', value: 'bounceIn' }, + { label: '向右弹入', value: 'bounceInLeft' }, + { label: '向左弹入', value: 'bounceInRight' }, + { label: '向上弹入', value: 'bounceInUp' }, + { label: '向下弹入', value: 'bounceInDown' }, + { label: '光速从右进入', value: 'lightSpeedInRight' }, + { label: '光速从左进入', value: 'lightSpeedInLeft' }, + { label: '光速从右退出', value: 'lightSpeedOutRight' }, + { label: '光速从左退出', value: 'lightSpeedOutLeft' }, + { label: 'Y轴旋转', value: 'flip' }, + { label: '中心X轴旋转', value: 'flipInX' }, + { label: '中心Y轴旋转', value: 'flipInY' }, + { label: '左长半径旋转', value: 'rollIn' }, + { label: '由小变大进入', value: 'zoomIn' }, + { label: '左变大进入', value: 'zoomInLeft' }, + { label: '右变大进入', value: 'zoomInRight' }, + { label: '向上变大进入', value: 'zoomInUp' }, + { label: '向下变大进入', value: 'zoomInDown' }, + { label: '向右滑动展开', value: 'slideInLeft' }, + { label: '向左滑动展开', value: 'slideInRight' }, + { label: '向上滑动展开', value: 'slideInUp' }, + { label: '向下滑动展开', value: 'slideInDown' } + ] + }, + { + label: '强调', + children: [ + { label: '弹跳', value: 'bounce' }, + { label: '闪烁', value: 'flash' }, + { label: '放大缩小', value: 'pulse' }, + { label: '放大缩小弹簧', value: 'rubberBand' }, + { label: '左右晃动', value: 'headShake' }, + { label: '左右扇形摇摆', value: 'swing' }, + { label: '放大晃动缩小', value: 'tada' }, + { label: '扇形摇摆', value: 'wobble' }, + { label: '左右上下晃动', value: 'jello' }, + { label: 'Y轴旋转', value: 'flip' } + ] + }, + { + label: '退出', + children: [ + { label: '渐隐', value: 'fadeOut' }, + { label: '向左退出', value: 'fadeOutLeft' }, + { label: '向右退出', value: 'fadeOutRight' }, + { label: '向上退出', value: 'fadeOutUp' }, + { label: '向下退出', value: 'fadeOutDown' }, + { label: '向左长距退出', value: 'fadeOutLeftBig' }, + { label: '向右长距退出', value: 'fadeOutRightBig' }, + { label: '向上长距退出', value: 'fadeOutUpBig' }, + { label: '向下长距退出', value: 'fadeOutDownBig' }, + { label: '旋转退出', value: 'rotateOut' }, + { label: '左顺时针旋转', value: 'rotateOutDownLeft' }, + { label: '右逆时针旋转', value: 'rotateOutDownRight' }, + { label: '左逆时针旋转', value: 'rotateOutUpLeft' }, + { label: '右逆时针旋转', value: 'rotateOutUpRight' }, + { label: '弹出', value: 'bounceOut' }, + { label: '向左弹出', value: 'bounceOutLeft' }, + { label: '向右弹出', value: 'bounceOutRight' }, + { label: '向上弹出', value: 'bounceOutUp' }, + { label: '向下弹出', value: 'bounceOutDown' }, + { label: '中心X轴旋转', value: 'flipOutX' }, + { label: '中心Y轴旋转', value: 'flipOutY' }, + { label: '左长半径旋转', value: 'rollOut' }, + { label: '由小变大退出', value: 'zoomOut' }, + { label: '左变大退出', value: 'zoomOutLeft' }, + { label: '右变大退出', value: 'zoomOutRight' }, + { label: '向上变大退出', value: 'zoomOutUp' }, + { label: '向下变大退出', value: 'zoomOutDown' }, + { label: '向左滑动收起', value: 'slideOutLeft' }, + { label: '向右滑动收起', value: 'slideOutRight' }, + { label: '向上滑动收起', value: 'slideOutUp' }, + { label: '向下滑动收起', value: 'slideOutDown' } + ] + } +]; diff --git a/src/config-center/types.ts b/src/config-center/types.ts index cd5ceb0..b791b3e 100644 --- a/src/config-center/types.ts +++ b/src/config-center/types.ts @@ -22,11 +22,18 @@ export interface IConfigItem { props: IConfigItemProps; type: EDoneJsonType; config: IDoneJsonConfig; - animations?: IConfigItemProps; + common_animations?: IConfigItemPropsCommonAnimations; + animations?: IConfigItemProps; //自定义动画效果 tag?: any; state?: IConfigItemState; //通过一个属性去控制多个属性就是有状态组件 tag_slot?: string; } +export interface IConfigItemPropsCommonAnimations { + val: string; + delay: string; + speed: string; + repeat: string; +} export interface IConfigItemProps { [key: string]: { title: string; diff --git a/src/config-center/vue/custom-vue/common-table/index.ts b/src/config-center/vue/custom-vue/common-table/index.ts index 4701e91..78242be 100644 --- a/src/config-center/vue/custom-vue/common-table/index.ts +++ b/src/config-center/vue/custom-vue/common-table/index.ts @@ -112,5 +112,11 @@ export const custom_vue_common_table: IConfigItem = { type: EConfigItemPropsType.Switch, val: false } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/vue/echarts/pie-charts/index.ts b/src/config-center/vue/echarts/pie-charts/index.ts index 6ea3d0c..486d68d 100644 --- a/src/config-center/vue/echarts/pie-charts/index.ts +++ b/src/config-center/vue/echarts/pie-charts/index.ts @@ -48,5 +48,11 @@ export const pie_charts: IConfigItem = { } ] } + }, + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' } }; diff --git a/src/config-center/vue/element-ui/button/index.ts b/src/config-center/vue/element-ui/button/index.ts index 5899721..67751e3 100644 --- a/src/config-center/vue/element-ui/button/index.ts +++ b/src/config-center/vue/element-ui/button/index.ts @@ -45,5 +45,11 @@ export const el_button_vue: IConfigItem = { val: false } }, - tag_slot: '按钮' + tag_slot: '按钮', + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' + } }; diff --git a/src/config-center/vue/element-ui/tag/index.ts b/src/config-center/vue/element-ui/tag/index.ts index eb585f4..a3681a6 100644 --- a/src/config-center/vue/element-ui/tag/index.ts +++ b/src/config-center/vue/element-ui/tag/index.ts @@ -34,5 +34,11 @@ export const el_tag_vue: IConfigItem = { val: false } }, - tag_slot: '标签' + tag_slot: '标签', + common_animations: { + val: '', + delay: 'delay-0s', + speed: 'slow', + repeat: 'infinite' + } }; diff --git a/src/utils/index.ts b/src/utils/index.ts index 3db19e7..34aef80 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -315,3 +315,9 @@ export const setArrItemByID = (id: string, key: string, val: any, json_arr: IDon }); }); }; +export const getCommonClass = (item: IDoneJson) => { + if (!item.common_animations || !item.common_animations.val) { + return ``; + } + return `common-ani animate__animated animate__${item.common_animations.val} animate__${item.common_animations.speed} animate__${item.common_animations.repeat} animate__${item.common_animations.delay}`; +}; diff --git a/src/views/demo/index.vue b/src/views/demo/index.vue index f519c6a..438e398 100644 --- a/src/views/demo/index.vue +++ b/src/views/demo/index.vue @@ -79,6 +79,13 @@ params: {} }); } + }, + { + name: '集成到平台效果预览', + title: '集成到平台效果预览', + onClick: () => { + window.open('http://svgpro.yaolm.top/'); + } } ]); interface IButtonList {