feat: 新增动画功能

This commit is contained in:
MTrun 2022-03-09 09:21:47 +08:00
parent b96c2f0d3e
commit a6e5dec2c0
10 changed files with 157 additions and 79 deletions

View File

@ -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() {

View File

@ -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 {

View File

@ -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

View File

@ -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 = {

View File

@ -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 }

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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 ''
}