Преглед на файлове

feat: 新增动画功能

MTrun преди 3 години
родител
ревизия
5c595fdedf

+ 0 - 2
src/main.ts

@@ -6,8 +6,6 @@ import { setupStore } from '@/store'
 import { setupNaive, setupDirectives, setupCustomComponents, setupPreviewPackages } from '@/plugins'
 import { AppProvider } from '@/components/AppProvider/index'
 import { setHtmlTheme } from '@/utils'
-
-// 引入动画
 import 'animate.css/animate.min.css'
 
 async function appInit() {

+ 1 - 0
src/packages/index.d.ts

@@ -19,6 +19,7 @@ export interface PublicConfigType {
   id: string
   rename?: string
   attr: { x: number; y: number; w: number; h: number; zIndex: number }
+  styles: { opacity: number, animations: string[] }
   setPosition: Function
 }
 export interface CreateComponentType extends PublicConfigType {

+ 5 - 0
src/packages/public/publicConfig.ts

@@ -7,6 +7,11 @@ export class publicConfig implements PublicConfigType {
   public rename = undefined
   // 基本信息
   public attr = { x: 0, y: 0, w: 500, h: 300, zIndex: -1 }
+  // 基本样式(动画,透明)
+  public styles = {
+    opacity: 1,
+    animations: []
+  }
   // 设置坐标
   public setPosition(x: number, y: number): void {
     this.attr.x = x

+ 4 - 1
src/plugins/icon.ts

@@ -46,6 +46,7 @@ DesktopOutline as DesktopOutlineIcon,
   Cut as CutIcon,
   Square as SquareIcon,
   ColorPalette as ColorPaletteIcon,
+  Leaf as LeafIcon
 } from '@vicons/ionicons5'
 
 import {
@@ -158,7 +159,9 @@ const ionicons5 = {
   SquareIcon,
   // 色彩选择
   ColorPaletteIcon,
-  ZAxisIcon
+  ZAxisIcon,
+  // 气球
+  LeafIcon
 }
 
 const carbon = {

+ 17 - 55
src/settings/animations/index.ts

@@ -1,6 +1,21 @@
-const animations = [
+export const animations = [
   {
-    label: '进入',
+    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: 'fadeIn' },
       { label: '向右进入', value: 'fadeInLeft' },
@@ -39,58 +54,5 @@ const animations = [
       { 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' }
-    ]
   }
 ]
-
-export { animations }

+ 95 - 0
src/views/chart/ContentConfigurations/components/ChartAnimation/index.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="go-chart-configurations-animations" v-if="targetData">
+    <n-button
+      class="clear-btn"
+      :disabled="!targetData.styles.animations.length"
+      @click="clearAnimation"
+    >
+      清除动画
+    </n-button>
+    <CollapseItem
+      v-for="(item, index) in animations"
+      :key="index"
+      :name="item.label"
+      :expanded="true"
+    >
+      <n-grid :x-gap="6" :y-gap="10" :cols="3">
+        <n-grid-item
+          class="animation-item go-transition-quick"
+          :class="[
+            activeIndex(childrenItem.value) && 'active',
+            hoverPreviewAnimate === childrenItem.value &&
+              `animate__animated  animate__${childrenItem.value}`
+          ]"
+          v-for="(childrenItem, index) in item.children"
+          :key="index"
+          @mouseover="hoverPreviewAnimate = childrenItem.value"
+          @click="addAnimation(childrenItem)"
+        >
+          {{ childrenItem.label }}
+        </n-grid-item>
+      </n-grid>
+    </CollapseItem>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed, ref, Ref } from 'vue'
+import { animations } from '@/settings/animations/index'
+import { CollapseItem } from '@/components/ChartItemSetting/index'
+import { CreateComponentType } from '@/packages/index.d'
+import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
+import { useDesignStore } from '@/store/modules/designStore/designStore'
+
+// 全局颜色
+const designStore = useDesignStore()
+const themeColor = ref(designStore.getAppTheme)
+
+const chartEditStore = useChartEditStore()
+const hoverPreviewAnimate = ref('')
+
+const targetData: Ref<CreateComponentType> = computed(() => {
+  const list = chartEditStore.getComponentList
+  const targetIndex = chartEditStore.fetchTargetIndex()
+  return list[targetIndex]
+})
+
+// * 选中样式
+const activeIndex = (value: string) => {
+  const selectValue = targetData.value.styles.animations
+  if (!selectValue.length) return false
+  return selectValue[0] === value
+}
+
+// * 清除动画
+const clearAnimation = () => {
+  targetData.value.styles.animations = []
+}
+
+// * 新增动画,现只支持一种
+const addAnimation = (item: { label: string; value: string }) => {
+  targetData.value.styles.animations = [item.value]
+}
+</script>
+
+<style lang="scss" scoped>
+@include go('chart-configurations-animations') {
+  padding: 20px 10px;
+  .clear-btn {
+    width: 100%;
+  }
+  .animation-item {
+    height: 50px;
+    line-height: 50px;
+    text-align: center;
+    cursor: pointer;
+    border-radius: 5px;
+    @include hover-border-color('hover-border-color');
+    &:hover,
+    &.active {
+      color: v-bind('themeColor');
+      border: 1px solid v-bind('themeColor');
+    }
+  }
+}
+</style>

+ 2 - 2
src/views/chart/ContentConfigurations/components/ChartSetting/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="go-chart-content-details" v-if="targetData">
+  <div class="go-chart-configurations-setting" v-if="targetData">
     <!-- 名称 -->
     <SettingItemBox name="名称">
       <n-input
@@ -39,6 +39,6 @@ const targetData: Ref<CreateComponentType> = computed(() => {
 </script>
 
 <style lang="scss" scoped>
-@include go('chart-content-details') {
+@include go('chart-configurations-setting') {
 }
 </style>

+ 16 - 13
src/views/chart/ContentConfigurations/index.vue

@@ -88,7 +88,12 @@ const { getDetails } = toRefs(useChartLayoutStore())
 const { setItem } = useChartLayoutStore()
 const chartEditStore = useChartEditStore()
 
-const { ConstructIcon, FlashIcon, DesktopOutlineIcon, RocketIcon } = icon.ionicons5
+const {
+  ConstructIcon,
+  FlashIcon,
+  DesktopOutlineIcon,
+  LeafIcon
+} = icon.ionicons5
 
 const ContentEdit = loadAsyncComponent(() => import('../ContentEdit/index.vue'))
 const CanvasPage = loadAsyncComponent(() =>
@@ -100,8 +105,8 @@ const ChartSetting = loadAsyncComponent(() =>
 const ChartData = loadAsyncComponent(() =>
   import('./components/ChartData/index.vue')
 )
-const ChartEvent = loadAsyncComponent(() =>
-  import('./components/ChartEvent/index.vue')
+const ChartAnimation = loadAsyncComponent(() =>
+  import('./components/ChartAnimation/index.vue')
 )
 
 const collapsed = ref<boolean>(getDetails.value)
@@ -119,9 +124,7 @@ const expandHindle = () => {
 const selectTarget = computed(() => {
   const selectId = chartEditStore.getTargetChart.selectId
   if (!selectId) return undefined
-  return chartEditStore.componentList[
-    chartEditStore.fetchTargetIndex()
-  ]
+  return chartEditStore.componentList[chartEditStore.fetchTargetIndex()]
 })
 
 watch(getDetails, newData => {
@@ -149,18 +152,18 @@ const canvasTabList = [
     icon: ConstructIcon,
     render: ChartSetting
   },
+  {
+    key: 'ChartAnimation',
+    title: '动画',
+    icon: LeafIcon,
+    render: ChartAnimation
+  },
   {
     key: 'ChartData',
     title: '数据',
     icon: FlashIcon,
     render: ChartData
-  },
-  {
-    key: 'ChartEvent',
-    title: '事件',
-    icon: RocketIcon,
-    render: ChartEvent
-  },
+  }
 ]
 </script>
 

+ 3 - 3
src/views/preview/components/RenderList/index.vue

@@ -1,9 +1,10 @@
 <template>
   <div
     class="chart-item"
+    :class="animationsClass(item.styles.animations)"
     v-for="(item, index) in localStorageInfo.componentList"
     :key="item.id"
-    :style="{ ...useComponentStyle(item.attr, index), ...useSizeStyle(item.attr) }"
+    :style="{ ...useComponentAttrStyle(item.attr, index), ...useSizeStyle(item.attr) }"
   >
     <component
       :is="item.key"
@@ -18,7 +19,7 @@
 import { PropType, computed } from 'vue'
 import { ChartEditStorageType } from '../../index.d'
 import { chartColors } from '@/settings/chartThemes/index'
-import { useSizeStyle, useComponentStyle } from '../../utils'
+import { useSizeStyle, useComponentAttrStyle, animationsClass } from '../../utils'
 
 const props = defineProps({
   localStorageInfo: {
@@ -27,7 +28,6 @@ const props = defineProps({
   }
 })
 
-
 // 主题色
 const themeSetting = computed(() => {
   const chartThemeSetting = props.localStorageInfo.editCanvasConfig.chartThemeSetting

+ 14 - 3
src/views/preview/utils/style.ts

@@ -2,8 +2,9 @@ import { PickCreateComponentType } from '@/packages/index.d'
 import { EditCanvasConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
 
 type AttrType = PickCreateComponentType<'attr'>
+type StylesType = PickCreateComponentType<'styles'>
 
-export const useComponentStyle = (attr: AttrType, index: number) => {
+export const useComponentAttrStyle = (attr: AttrType, index: number) => {
   const componentStyle = {
     zIndex: index + 1,
     left: `${attr.x}px`,
@@ -15,7 +16,7 @@ export const useComponentStyle = (attr: AttrType, index: number) => {
 export const useSizeStyle = (attr: AttrType, scale?: number) => {
   const sizeStyle = {
     width: `${scale ? scale * attr.w : attr.w}px`,
-    height: `${scale ? scale * attr.h : attr.h}px`,
+    height: `${scale ? scale * attr.h : attr.h}px`
   }
   return sizeStyle
 }
@@ -24,7 +25,9 @@ export const useEditCanvasConfigStyle = (canvas: EditCanvasConfigType) => {
   // 背景
   const computedBackground = canvas.selectColor
     ? { background: canvas.background }
-    : { background: `url(${canvas.backgroundImage}) no-repeat center/100% !important` }
+    : {
+        background: `url(${canvas.backgroundImage}) no-repeat center/100% !important`
+      }
   return {
     position: 'relative',
     width: canvas.width ? `${canvas.width || 100}px` : '100%',
@@ -32,3 +35,11 @@ export const useEditCanvasConfigStyle = (canvas: EditCanvasConfigType) => {
     ...computedBackground
   }
 }
+
+// 动画
+export const animationsClass = (animations: string[]) => {
+  if (animations.length) {
+    return `animate__animated  animate__${animations[0]}`
+  }
+  return ''
+}